From 682c6da83dfbc00d8a570238ee71e585dc602c7a Mon Sep 17 00:00:00 2001 From: Fran Boon Date: Thu, 26 Jun 2014 17:49:36 +0100 Subject: [PATCH] Organisation Type can be Multiple & Hierarchical Tweak CRUD Strings for consistency (& their translations) S3SQLInlineLink reads field.default & field.writable --- VERSION | 2 +- controllers/asset.py | 32 +- controllers/inv.py | 29 +- controllers/project.py | 25 +- languages/bs.py | 5 +- languages/en-gb.py | 3 +- languages/km.py | 3 +- languages/ne.py | 2 +- languages/prs.py | 2 +- languages/ps.py | 2 +- languages/vi.py | 6 +- modules/s3/s3filter.py | 3 +- modules/s3/s3forms.py | 30 +- modules/s3/s3import.py | 144 ++- modules/s3/s3resource.py | 2 +- modules/s3/s3widgets.py | 10 +- modules/s3/s3xml.py | 1 + modules/s3cfg.py | 12 + modules/s3db/cap.py | 6 +- modules/s3db/event.py | 6 +- modules/s3db/org.py | 938 ++++++++++-------- modules/s3db/project.py | 4 +- modules/s3menus.py | 1 - private/templates/ARC/config.py | 13 +- private/templates/CRMT/config.py | 10 +- private/templates/CRMT/facility.csv | 214 ++-- private/templates/CRMT/organisation.csv | 46 +- private/templates/DRMP/config.py | 3 +- private/templates/DRRPP/controllers.py | 63 +- private/templates/EUROSHA/config.py | 36 +- .../templates/IFRC/Demo/project_location.csv | 2 +- private/templates/IFRC/config.py | 82 +- private/templates/IFRC/menus.py | 47 +- private/templates/India/config.py | 3 +- private/templates/LK/config.py | 3 +- private/templates/MCOP/config.py | 14 +- private/templates/NEREIDS/config.py | 3 +- private/templates/NYC/config.py | 16 +- private/templates/OCHA/config.py | 47 +- private/templates/Philippines/config.py | 5 +- private/templates/SandyRelief/config.py | 50 +- private/templates/Syria/config.py | 3 +- private/templates/Yolanda/config.py | 14 +- .../templates/Yolanda/gis_layer_feature.csv | 2 +- private/templates/default/config.py | 4 + static/formats/drrp.xsl | 50 +- static/formats/s3csv/org/organisation.xsl | 100 +- static/formats/s3csv/project/organisation.xsl | 32 +- 48 files changed, 1153 insertions(+), 977 deletions(-) diff --git a/VERSION b/VERSION index 94079e2799..2caa747386 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -54ac923 (2014-06-25 17:52:43) \ No newline at end of file +2c23922 (2014-06-26 17:49:36) \ No newline at end of file diff --git a/controllers/asset.py b/controllers/asset.py index 4e0c45ec94..a48d8a5e83 100644 --- a/controllers/asset.py +++ b/controllers/asset.py @@ -51,7 +51,8 @@ def catalog(): """ RESTful CRUD controller """ return s3_rest_controller("supply", "catalog", - rheader=s3db.supply_catalog_rheader) + rheader = s3db.supply_catalog_rheader, + ) # ----------------------------------------------------------------------------- def item(): @@ -91,8 +92,8 @@ def catalog_item(): """ return s3_rest_controller("supply", "catalog_item", - csv_template=("supply", "catalog_item"), - csv_stylesheet=("supply", "catalog_item.xsl"), + csv_template = ("supply", "catalog_item"), + csv_stylesheet = ("supply", "catalog_item.xsl"), ) # ----------------------------------------------------------------------------- @@ -115,25 +116,24 @@ def item_category(): def supplier(): """ RESTful CRUD controller """ - get_vars["organisation.organisation_type_id$name"] = "Supplier" + get_vars["organisation_type.name"] = "Supplier" # Load model table = s3db.org_organisation # Modify CRUD Strings - ADD_SUPPLIER = T("Add Supplier") s3.crud_strings.org_organisation = Storage( - label_create=ADD_SUPPLIER, - title_display=T("Supplier Details"), - title_list=T("Suppliers"), - title_update=T("Edit Supplier"), - title_upload=T("Import Suppliers"), - label_list_button=T("List Suppliers"), - label_delete_button=T("Delete Supplier"), - msg_record_created=T("Supplier added"), - msg_record_modified=T("Supplier updated"), - msg_record_deleted=T("Supplier deleted"), - msg_list_empty=T("No Suppliers currently registered") + label_create = T("Create Supplier"), + title_display = T("Supplier Details"), + title_list = T("Suppliers"), + title_update = T("Edit Supplier"), + title_upload = T("Import Suppliers"), + label_list_button = T("List Suppliers"), + label_delete_button = T("Delete Supplier"), + msg_record_created = T("Supplier added"), + msg_record_modified = T("Supplier updated"), + msg_record_deleted = T("Supplier deleted"), + msg_list_empty = T("No Suppliers currently registered") ) # Modify filter_widgets diff --git a/controllers/inv.py b/controllers/inv.py index c8dfd5c406..fa8b6d6835 100644 --- a/controllers/inv.py +++ b/controllers/inv.py @@ -396,25 +396,24 @@ def supplier(): Filtered version of the organisation() REST controller """ - get_vars["organisation.organisation_type_id$name"] = "Supplier" + get_vars["organisation_type.name"] = "Supplier" # Load model table = s3db.org_organisation # Modify CRUD Strings - ADD_SUPPLIER = T("Add Supplier") s3.crud_strings.org_organisation = Storage( - label_create=ADD_SUPPLIER, - title_display=T("Supplier Details"), - title_list=T("Suppliers"), - title_update=T("Edit Supplier"), - title_upload=T("Import Suppliers"), - label_list_button=T("List Suppliers"), - label_delete_button=T("Delete Supplier"), - msg_record_created=T("Supplier added"), - msg_record_modified=T("Supplier updated"), - msg_record_deleted=T("Supplier deleted"), - msg_list_empty=T("No Suppliers currently registered") + label_create = T("Create Supplier"), + title_display = T("Supplier Details"), + title_list = T("Suppliers"), + title_update = T("Edit Supplier"), + title_upload = T("Import Suppliers"), + label_list_button = T("List Suppliers"), + label_delete_button = T("Delete Supplier"), + msg_record_created = T("Supplier added"), + msg_record_modified = T("Supplier updated"), + msg_record_deleted = T("Supplier deleted"), + msg_list_empty = T("No Suppliers currently registered") ) # Modify filter_widgets @@ -1050,7 +1049,7 @@ def prep(r): listadd = False, ) - output = s3_rest_controller(rheader=s3db.inv_recv_rheader) + output = s3_rest_controller(rheader = s3db.inv_recv_rheader) return output # ----------------------------------------------------------------------------- @@ -1418,7 +1417,7 @@ def track_item(): ) s3.filter = (FS("expiry_date") != None) - output = s3_rest_controller(rheader=s3db.inv_rheader) + output = s3_rest_controller(rheader = s3db.inv_rheader) return output # ============================================================================= diff --git a/controllers/project.py b/controllers/project.py index da3fb36ce9..9c82dfd838 100644 --- a/controllers/project.py +++ b/controllers/project.py @@ -724,26 +724,25 @@ def partners(): """ # @ToDo: This could need to be a deployment setting - get_vars["organisation.organisation_type_id$name"] = \ + get_vars["organisation_type.name"] = \ "Academic,Bilateral,Government,Intergovernmental,NGO,UN agency" # Load model table = s3db.org_organisation # Modify CRUD Strings - ADD_PARTNER = T("Add Partner Organization") s3.crud_strings.org_organisation = Storage( - label_create=ADD_PARTNER, - title_display=T("Partner Organization Details"), - title_list=T("Partner Organizations"), - title_update=T("Edit Partner Organization"), - title_upload=T("Import Partner Organizations"), - label_list_button=T("List Partner Organizations"), - label_delete_button=T("Delete Partner Organization"), - msg_record_created=T("Partner Organization added"), - msg_record_modified=T("Partner Organization updated"), - msg_record_deleted=T("Partner Organization deleted"), - msg_list_empty=T("No Partner Organizations currently registered") + label_create = T("Create Partner Organization"), + title_display = T("Partner Organization Details"), + title_list = T("Partner Organizations"), + title_update = T("Edit Partner Organization"), + title_upload = T("Import Partner Organizations"), + label_list_button = T("List Partner Organizations"), + label_delete_button = T("Delete Partner Organization"), + msg_record_created = T("Partner Organization added"), + msg_record_modified = T("Partner Organization updated"), + msg_record_deleted = T("Partner Organization deleted"), + msg_list_empty = T("No Partner Organizations currently registered") ) return s3db.org_organisation_controller() diff --git a/languages/bs.py b/languages/bs.py index 236154411e..c8488cb7e0 100644 --- a/languages/bs.py +++ b/languages/bs.py @@ -440,7 +440,6 @@ 'Add New Scenario': 'Dodaj novi scenarij', 'Add New School District': 'Dodaj novi školski rejon', 'Add New School Report': 'Dodaj novi izvještaj o školama', -'Add New Sector': 'Dodaj novi sektor', 'Add New Sent Item': 'Dodaj novu poslanu stavku', 'Add New Setting': 'Dodaj novu postavku', 'Add New Shelter': 'Dodaj novo sklonište', @@ -489,7 +488,6 @@ 'Add Organization to Project': 'Dodaj organizaciju projektu', 'Add Participant': 'Dodaj učesnika', 'Add Partner': 'Dodaj partnera', -'Add Partner Organization': 'Dodaj partnersku organizaciju', 'Add Peer': 'Dodaj saradnika', 'Add People to Commitment': 'Dodaj ljude u zaduženje', 'Add Person': 'Dodaj osobu', @@ -561,7 +559,6 @@ 'Add Sub-Category': 'Traži potkategoriju', 'Add Subscription': 'Dodaj pretplatu', 'Add Subsector': 'Dodaj podsektor', -'Add Supplier': 'Dodaj dobavljača', 'Add Survey Answer': 'Dodaj odgovor na istraživanje', 'Add Survey Question': 'Dodajte anketno pitanje', 'Add Survey Section': 'Dodajte anketnu sekciju', @@ -1725,6 +1722,7 @@ 'Create Office Type': 'Kreiraj tip kancelarije', 'Create Organization': 'Kreiraj organizaciju', 'Create Organization Type': 'Kreiraj tip organizacije', +'Create Partner Organization': 'Kreiraj partnersku organizaciju', 'Create Personal Effects': 'Kreiraj lične uticaja', 'Create PoI Type': 'Kreiraj tačku interesa', 'Create Point of Interest': 'Kreiraj tačku interesa', @@ -1756,6 +1754,7 @@ 'Create Staff Member': 'Kreiraj člana osoblja', 'Create Status': 'Kreiraj status', 'Create Status Report': 'Kreiraj statusni izvještaj', +'Create Supplier': 'Kreiraj dobavljača', 'Create Symbology': 'Kreiraj značenje simbola', 'Create Tag': 'Kreiraj oznaku', 'Create Task': 'Kreiraj zadatak', diff --git a/languages/en-gb.py b/languages/en-gb.py index f819f115b4..4f752736c9 100644 --- a/languages/en-gb.py +++ b/languages/en-gb.py @@ -12,8 +12,6 @@ 'Add New Program': 'Add New Programme', 'Add Organization Domain': 'Add Organisation Domain', 'Add Organization to Project': 'Add Organisation to Project', -'Add Partner Organization': 'Add Partner Organisation', -'Add Partner Organizations': 'Add Partner Organisations', 'Add Program Hours': 'Add Programme Hours', 'Canceled': 'Cancelled', 'Cannot make an Organization a branch of itself!': 'Cannot make an Organisation a branch of itself!', @@ -39,6 +37,7 @@ 'Create Catalog Item': 'Create Catalogue Item', 'Create Organization': 'Create Organisation', 'Create Organization Type': 'Create Organisation Type', +'Create Partner Organization': 'Create Partner Organisation', 'Create Program': 'Create Programme', 'Credentialling Organization': 'Credentialling Organisation', 'Current Owned By (Organization/Branch)': 'Current Owned By (Organisation/Branch)', diff --git a/languages/km.py b/languages/km.py index 39c5944a60..3cc10208cd 100644 --- a/languages/km.py +++ b/languages/km.py @@ -206,7 +206,6 @@ 'Add Organization to Activity': 'បន្ថែម​សកម្មភាព​របស់​អង្គការ', 'Add Organization to Project': 'បន្ថែម​អង្គការ​ទៅ​គម្រោង', 'Add Participant': 'បន្ថែម​អ្នក​ចូលរួម', -'Add Partner Organization': 'បន្ថែម​អង្គការ​ដៃគូរ', 'Add Person': 'បន្ថែម​មនុស្ស', 'Add Point': 'បន្ថែម​ចំណុច', 'Add Polygon': 'បន្ថែម​ពហុកោណថ្មី', @@ -217,6 +216,7 @@ 'Add Region': 'បន្ថែម​តំបន់', 'Add Resource Type': 'បន្ថែម​ប្រភេទ​ធនធាន', 'Add Response Summary': 'បន្ថែមការសង្ខេប​អំពី​ចម្លើយ​តប', +'Add Sector': 'បន្ថែម​ផ្នែក', 'Add Sector to Organization': 'បន្ថែមផ្នែកទៅ​អង្គការ', 'Add Sector to Project': 'បន្ថែម​ផ្នែក​​ទៅ​គម្រោង', 'Add Sector to Theme': 'បន្ថែម​ផ្នែក​ទៅ​ស្បែក', @@ -591,6 +591,7 @@ 'Create Office': 'បន្ថែម​ការិយាល័យ', 'Create Organization Type': 'បន្ថែម​ប្រភេទ​អង្គការ', 'Create Organization': 'បន្ថែម​អង្គការ', +'Create Partner Organization': 'បន្ថែម​អង្គការ​ដៃគូរ', 'Create PoI Type': 'បន្ថែម​ប្រភេទ PoI', 'Create Point of Interest': 'បន្ថែម​ចំណុច​ចាប់អារម្មណ៍​ថ្មី', 'Create Policy or Strategy': 'បន្ថែម​គោលនយោបាយ ឬ​យុទ្ធសាស្ត្រ', diff --git a/languages/ne.py b/languages/ne.py index bc7f9f3754..d29b2e7e4b 100644 --- a/languages/ne.py +++ b/languages/ne.py @@ -215,7 +215,6 @@ 'Add Organization to Activity': 'कृयाकलापको बनावट राख्नुहोस्', 'Add Organization to Project': 'परियोजनामा संस्था राख्नुहोस्', 'Add Participant': 'सहभागी राख्नुहोस्', -'Add Partner Organization': 'सहकारी संस्था राख्नुहोस्', 'Add Person': 'ब्यक्ति राख्नुहोस्', "Add Person's Details": 'ब्यक्तिको विवरण राख्नुहोस्', 'Add PoI Type': 'पोलको प्रकार राख्नुहोस्', @@ -622,6 +621,7 @@ 'Create Network': 'नेटवर्क राख्नुहोस् ', 'Create Office Type': 'कार्यलयको प्रकार राख्नुहोस्', 'Create Organization Type': 'संस्थाको प्रकार राख्नुहोस्', +'Create Partner Organization': 'सहकारी संस्था राख्नुहोस्', 'Create Program': 'कार्यक्रम', 'Create Project': 'परियोजना राख्नुहोस्', 'Create Projection': 'योजना राख्नुहोस्', diff --git a/languages/prs.py b/languages/prs.py index 5260dcea8c..7a67e4ca4c 100644 --- a/languages/prs.py +++ b/languages/prs.py @@ -211,7 +211,6 @@ 'Add Organization to Activity': 'سازمان فعالیت را اضافه کنید', 'Add Organization to Project': 'پروژه موسسه را اضافه نمایید', 'Add Participant': 'شریک را اضافه نمایید', -'Add Partner Organization': 'همکار موسسه را اضافه نمایید', 'Add Person': 'شخص را اضافه نمایید', "Add Person's Details": 'مشخصات شخص را اضافه نمایید', 'Add PoI Type': 'نوع POL را اضافه نمایید', @@ -618,6 +617,7 @@ 'Create Network': 'شبکه را اضافه نمایید', 'Create Office Type': 'نوع اداره را اضافه نمایید', 'Create Organization Type': 'نوع موسسه را اضافه نمایید', +'Create Partner Organization': 'همکار موسسه را اضافه نمایید', 'Create Program': 'برنامه را اضافه نمایید', 'Create Project': 'پروژه را اضافه نمایید', 'Create Projection': 'تصویر را اضافه نمایید', diff --git a/languages/ps.py b/languages/ps.py index 496f2a86db..ea206d4fa9 100644 --- a/languages/ps.py +++ b/languages/ps.py @@ -211,7 +211,6 @@ 'Add Organization to Activity': 'اضافه کړی د فعالیت موسسه', 'Add Organization to Project': 'اضافه کړی موسسه پروژی ته', 'Add Participant': 'اضافه کړی ګډونوال', -'Add Partner Organization': 'اضافه کړی همکاره موسسی', 'Add Person': 'اضافه کړی کسان', "Add Person's Details": 'اضافه کړی د کسانو معلومات', 'Add PoI Type': 'اضافه کړی د پل (pol ) بڼه', @@ -619,6 +618,7 @@ 'Create Network': 'اضافه کړی شبکه', 'Create Office Type': 'اضافه کړی د دفتر بڼه', 'Create Organization Type': 'اضافه کړی د موسسی بڼه', +'Create Partner Organization': 'اضافه کړی همکاره موسسی', 'Create Program': 'اضافه کړی پروګرام', 'Create Project': 'اضافه کړی پروژه ', 'Create Projection': 'اضافه کړی نقشه', diff --git a/languages/vi.py b/languages/vi.py index dc00386f0e..b901f53ca4 100644 --- a/languages/vi.py +++ b/languages/vi.py @@ -285,8 +285,6 @@ 'Add Organization to Project': 'Thêm tổ chức tham gia dự án', 'Add Parser Settings': 'Thêm cài đặt cú pháp', 'Add Participant': 'Thêm người tham dự', -'Add Partner Organization': 'Thêm tổ chức đối tác', -'Add Partner Organizations': 'Thêm tổ chức đối tác', 'Add Person to Commitment': 'Thêm đối tượng cam kết', 'Add Person': 'Thêm họ tên', 'Add Photo': 'Thêm ảnh', @@ -314,8 +312,6 @@ 'Add Storage Location ': 'Thêm vị trí lưu trữ', 'Add Storage Location': 'Thêm vị trí lưu trữ', 'Add Sub-Category': 'Thêm danh mục cấp dưới', -'Add Supplier': 'Thêm nhà cung cấp', -'Add Suppliers': 'Thêm nhà cung cấp', 'Add Survey Answer': 'Thêm trả lời khảo sát', 'Add Survey Question': 'Thêm câu hỏi khảo sát', 'Add Survey Section': 'Thêm phần Khảo sát', @@ -934,6 +930,7 @@ 'Create Office': 'Thêm văn phòng', 'Create Organization Type': 'Thêm loại hình tổ chức', 'Create Organization': 'Thêm tổ chức', +'Create Partner Organization': 'Thêm tổ chức đối tác', 'Create PDF': 'Tạo PDF', 'Create Program': 'Thêm chương trình', 'Create Project': 'Thêm dự án', @@ -950,6 +947,7 @@ 'Create Skill': 'Thêm kỹ năng', 'Create Staff Member': 'Thêm cán bộ', 'Create Status': 'Thêm trạng thái', +'Create Supplier': 'Thêm nhà cung cấp', 'Create Symbology': 'Thêm biểu tượng', 'Create Task': 'Thêm nhiệm vụ', 'Create Team': 'Tạo đội TNV', diff --git a/modules/s3/s3filter.py b/modules/s3/s3filter.py index 9ec9fda8a1..23b179066b 100644 --- a/modules/s3/s3filter.py +++ b/modules/s3/s3filter.py @@ -48,7 +48,6 @@ from gluon.contrib.simplejson.ordered_dict import OrderedDict from gluon import * -from gluon.sqlhtml import MultipleOptionsWidget from gluon.storage import Storage from gluon.tools import callback @@ -1772,7 +1771,7 @@ def variable(self, resource, get_vars=None): return variable # Detect and resolve __typeof queries - BELONGS = current.db._adapter.BELONGS + #BELONGS = current.db._adapter.BELONGS resolve = S3ResourceQuery._resolve_hierarchy selector = resource.prefix_selector(selector) for key, value in get_vars.items(): diff --git a/modules/s3/s3forms.py b/modules/s3/s3forms.py index 632cf895e4..e27b75a5bb 100644 --- a/modules/s3/s3forms.py +++ b/modules/s3/s3forms.py @@ -45,7 +45,6 @@ from gluon.contrib.simplejson.ordered_dict import OrderedDict from gluon import * -from gluon.languages import lazyT from gluon.storage import Storage from gluon.sqlhtml import StringWidget from gluon.tools import callback @@ -1621,12 +1620,12 @@ def resolve(self, resource): fname = self._formname(separator = "_") field = Field(fname, "text", comment = options.get("comment", None), - label = label, - widget = self, default = self.extract(resource, None), + label = label, represent = self.represent, - requires = self.parse, required = options.get("required", False), + requires = self.parse, + widget = self, ) return (self, None, field) @@ -2747,7 +2746,7 @@ def extract(self, resource, record_id): @param resource: the resource the record belongs to @param record_id: the record ID - + @return: list of component record IDs this record is linked to via the link table """ @@ -2755,28 +2754,34 @@ def extract(self, resource, record_id): self.resource = resource component, link = self.get_link() - values = [] if record_id: rkey = component.rkey rows = link.select([rkey], as_rows=True) if rows: rkey = str(link.table[rkey]) values = [row[rkey] for row in rows] + else: + values = [] + else: + # Use default + values = [link.table[self.options.field].default] + return values # ------------------------------------------------------------------------- def __call__(self, field, value, **attributes): """ - Widget renderer, currently supports groupedopts (default) and - multiselect widgets (hierarchy planned). + Widget renderer, currently supports multiselect (default), hierarchy + and groupedopts widgets. @param field: the input field @param value: the value to populate the widget @param attributes: attributes for the widget - + @return: the widget """ + options = self.options component, link = self.get_link() # Field dummy @@ -2784,7 +2789,6 @@ def __call__(self, field, value, **attributes): type = link.table[component.rkey].type) # Widget type - options = self.options widget = options.get("widget") if widget != "hierarchy": # Get the selectable entries for the widget and construct @@ -2830,6 +2834,12 @@ def __call__(self, field, value, **attributes): # Render the widget attr = dict(attributes) attr["_id"] = field.name + if not link.table[options.field].writable: + _class = attr.get("_class", None) + if _class: + attr["_class"] = "%s hide" % _class + else: + attr["_class"] = "hide" widget = w(dummy_field, value, **attr) # Append the attached script to jquery_ready diff --git a/modules/s3/s3import.py b/modules/s3/s3import.py index f707b66fdc..930ffd675c 100644 --- a/modules/s3/s3import.py +++ b/modules/s3/s3import.py @@ -37,7 +37,6 @@ import cPickle import os import sys -import tempfile import urllib2 # Needed for error handling on fetch import uuid from copy import deepcopy @@ -238,22 +237,16 @@ def apply_method(self, r, **attr): else: return dict(form=None) - # @todo: clean this up - source = None - open_file = None - transform = None - upload_id = None - items = None # @todo get the data from either get_vars or post_vars appropriately # for post -> commit_items would need to add the uploadID - if "transform" in r.get_vars: - transform = r.get_vars["transform"] - if "filename" in r.get_vars: - source = r.get_vars["filename"] + transform = r.get_vars.get("transform", None) + source = r.get_vars.get("filename", None) if "job" in r.post_vars: upload_id = r.post_vars["job"] elif "job" in r.get_vars: upload_id = r.get_vars["job"] + else: + upload_id = None items = self._process_item_list(upload_id, r.vars) if "delete" in r.get_vars: r.http = "DELETE" @@ -454,11 +447,10 @@ def display_job(self, upload_id): request = self.request table = self.upload_table job_id = self.job_id - output = dict() if job_id is None: # redirect to the start page (removes all vars) query = (table.id == upload_id) - row = db(query).update(status = 2) # in error + db(query).update(status = 2) # in error current.session.warning = self.messages.no_records_to_import redirect(URL(r=request, f=self.function, args=["import"])) @@ -785,13 +777,13 @@ def _create_upload_dataTable(self): table = self.upload_table s3.filter = (table.controller == controller) & \ (table.function == function) - fields = ["id", - "filename", - "created_on", - "user_id", - "replace_option", - "status", - ] + #fields = ["id", + # "filename", + # "created_on", + # "user_id", + # "replace_option", + # "status", + # ] self._use_upload_table() @@ -1106,11 +1098,11 @@ def _commit_import_job(self, upload_id, items): # Loop through each row and delete the items not required self._store_import_details(job_id, "preDelete") - for id in rows: - if str(id) not in items: + for _id in rows: + if str(_id) not in items: # @todo: replace with a helper method from the API - _debug("Deleting item.id = %s" % id) - db(itemTable.id == id).delete() + _debug("Deleting item.id = %s" % _id) + db(itemTable.id == _id).delete() #**************************************************************** # EXPERIMENTAL @@ -1123,9 +1115,9 @@ def _commit_import_job(self, upload_id, items): self._store_import_details(job_id, "preImportTree") # Now commit the remaining items - msg = resource.import_xml(None, - job_id = job_id, - ignore_errors = True) + resource.import_xml(None, + job_id = job_id, + ignore_errors = True) return resource.error is None # ------------------------------------------------------------------------- @@ -1177,10 +1169,10 @@ def _update_upload_job(self, upload_id): totalRecords = 0 query = (self.upload_table.id == upload_id) - result = db(query).update(summary_added=totalRecords, - summary_error=totalErrors, - summary_ignored = totalIgnored, - status = 3) + db(query).update(summary_added=totalRecords, + summary_error=totalErrors, + summary_ignored = totalIgnored, + status = 3) # Commit the changes db.commit() @@ -1248,7 +1240,7 @@ def _dataTable(self, NOTE: limit - totalDisplayRecords = total cached """ - from s3.s3data import S3DataTable + from s3data import S3DataTable request = self.request resource = self.resource s3 = current.response.s3 @@ -1260,7 +1252,7 @@ def _dataTable(self, representation = request.representation # Datatable Filter - totalrows = displayrows = None + totalrows = None if representation == "aadata": searchq, orderby, left = resource.datatable_filter(list_fields, request.get_vars) @@ -1272,10 +1264,10 @@ def _dataTable(self, # Start/Limit if representation == "aadata": - vars = request.get_vars - start = vars.get("iDisplayStart", None) - limit = vars.get("iDisplayLength", None) - sEcho = int(vars.sEcho or 0) + get_vars = request.get_vars + start = get_vars.get("iDisplayStart", None) + limit = get_vars.get("iDisplayLength", None) + sEcho = int(get_vars.sEcho or 0) else: # catch all start = 0 limit = s3.ROWSPERPAGE @@ -1471,7 +1463,7 @@ def _decode_data(field, value): return int(value) elif field.type == "double" or \ field.type == "decimal": - return double(value) + return float(value) elif field.type == "boolean": if value and not str(value)[:1].upper() in ["F", "0"]: return "T" @@ -1931,8 +1923,6 @@ def deduplicate(self): self.uid = original[UID] data.update({UID:self.uid}) - return - # ------------------------------------------------------------------------- def authorize(self): """ @@ -1949,10 +1939,6 @@ def authorize(self): if not auth.override and tablename.split("_", 1)[0] in auth.PROTECTED: return False - xml = current.xml - DELETED = xml.DELETED - REPLACEDBY = xml.REPLACEDBY - # Determine the method METHOD = self.METHOD if self.data.deleted is True: @@ -2542,7 +2528,6 @@ def _dynamic_defaults(self, data): fn = k[1:] if fn in self.table.fields and fn not in data: data[fn] = v - return # ------------------------------------------------------------------------- def _mandatory_fields(self): @@ -3060,8 +3045,6 @@ def add_item(self, if item_id: entry.update(item_id=item_id) - references = item.references - # Parent reference if parent is not None: entry = Storage(item_id=parent.item_id, @@ -3249,14 +3232,14 @@ def lookahead(self, uid = relement.get(attr, None) if attr == UID: _uid = import_uid(uid) - id = _uid and id_map and id_map.get(_uid, None) or None + _id = _uid and id_map and id_map.get(_uid, None) or None else: _uid = None - id = None + _id = None entry = Storage(tablename=tablename, element=relement, uid=uid, - id=id, + id=_id, item_id=None) # Add entry to directory if uid and directory is not None: @@ -3477,16 +3460,19 @@ def get_tree(self): """ if self.tree is not None: - return tree + return self.tree else: xml = current.xml + ATTRIBUTE = xml.ATTRIBUTE + UID = xml.UID root = etree.Element(xml.TAG.root) for item in self.items.values(): - if item.element is not None and not item.parent: + element = item.element + if element is not None and not item.parent: if item.tablename == self.table._tablename or \ - item.element.get(xml.UID, None) or \ - item.element.get(xml.ATTRIBUTE.tuid, None): - root.append(deepcopy(item.element)) + element.get(UID, None) or \ + element.get(ATTRIBUTE.tuid, None): + root.append(deepcopy(element)) return etree.ElementTree(root) # ------------------------------------------------------------------------- @@ -3632,7 +3618,7 @@ def extractImporterLine(self, path, details): argCnt = len(details) if argCnt == 4 or argCnt == 5: - # remove any spaces and enclosing double quote + # Remove any spaces and enclosing double quote app = details[0].strip('" ') res = details[1].strip('" ') request = current.request @@ -3669,13 +3655,15 @@ def extractImporterLine(self, path, details): self.errorList.append( "Failed to find a transform file %s, Giving up." % xslFileName) return - vars = None + if argCnt == 5: - vars = details[4] - self.tasks.append([1, app, res, csv, xsl, vars]) + extra_data = details[4] + else: + extra_data = None + self.tasks.append([1, app, res, csv, xsl, extra_data]) else: self.errorList.append( - "prepopulate error: job not of length 4. %s job ignored" % task) + "prepopulate error: job not of length 4, ignored: %" % details) # ------------------------------------------------------------------------- def extractSpecialistLine(self, path, details): @@ -3742,7 +3730,6 @@ def execute_import_task(self, task): # Check if the source file is accessible filename = task[3] if filename[:7] == "http://": - import urllib2 req = urllib2.Request(url=filename) try: f = urllib2.urlopen(req) @@ -3781,10 +3768,10 @@ def execute_import_task(self, task): auth.rollback = True try: # @todo: add extra_data and file attachments - result = resource.import_xml(csv, - format="csv", - stylesheet=task[4], - extra_data=extra_data) + resource.import_xml(csv, + format="csv", + stylesheet=task[4], + extra_data=extra_data) except SyntaxError, e: self.errorList.append("WARNING: import error - %s (file: %s, stylesheet: %s)" % (e, filename, task[4])) @@ -4017,21 +4004,20 @@ def import_image(self, for row in reader: if row != None: - id = row["id"] - image = row["file"] # Open the file + image = row["file"] try: # Extract the path to the CSV file, image should be in # this directory, or relative to it - (path, file) = os.path.split(filename) - imagepath= os.path.join(path, image) + path = os.path.split(filename)[0] + imagepath = os.path.join(path, image) openFile = open(imagepath, "rb") except IOError: current.log.error("Unable to open image file %s" % image) continue image_source = StringIO(openFile.read()) # Get the id of the resource - query = base_query & (idfield == id) + query = base_query & (idfield == row["id"]) record = db(query).select(limitby=(0, 1) ).first() try: @@ -4095,33 +4081,33 @@ def import_remote_csv(self, url, prefix, resource, stylesheet): os.chdir(tempPath) try: - file = fetch(url) + _file = fetch(url) except urllib2.URLError, exception: current.log.error(exception) # Revert back to the working directory as before. os.chdir(cwd) return - fp = StringIO(file) + fp = StringIO(_file) if extension == "zip": # Need to unzip import zipfile myfile = zipfile.ZipFile(fp) files = myfile.infolist() - for _file in files: - filename = _file.filename + for f in files: + filename = f.filename extension = filename.split(".")[-1] if extension == "csv": - file = myfile.read(filename) - f = open(filename, "w") - f.write(file) - f.close() + _file = myfile.read(filename) + _f = open(filename, "w") + _f.write(_file) + _f.close() break myfile.close() else: filename = url.split("/")[-1] f = open(filename, "w") - f.write(file) + f.write(_file) f.close() # Revert back to the working directory as before. diff --git a/modules/s3/s3resource.py b/modules/s3/s3resource.py index d072ef35c1..799b6c3ac4 100644 --- a/modules/s3/s3resource.py +++ b/modules/s3/s3resource.py @@ -56,8 +56,8 @@ import gluon.contrib.simplejson as json # fallback to pure-Python module from gluon import current +from gluon.html import A, TAG from gluon.http import HTTP -from gluon.html import TAG from gluon.validators import IS_EMPTY_OR from gluon.dal import Row, Rows, Table, Field, Expression from gluon.storage import Storage diff --git a/modules/s3/s3widgets.py b/modules/s3/s3widgets.py index e4577c35dd..fd258704ad 100644 --- a/modules/s3/s3widgets.py +++ b/modules/s3/s3widgets.py @@ -4735,8 +4735,14 @@ def __call__(self, field, value, **attr): attr["_class"] = "multiselect-widget" multiple_opt = self.multiple - w = MultipleOptionsWidget if multiple_opt else OptionsWidget - widget = TAG[""](w.widget(field, value, **attr), requires = field.requires) + if multiple_opt: + w = MultipleOptionsWidget + else: + w = OptionsWidget + if value: + value = str(value[0]) + widget = TAG[""](w.widget(field, value, **attr), + requires = field.requires) # Filter and header for multiselect options list filter_opt = self.filter diff --git a/modules/s3/s3xml.py b/modules/s3/s3xml.py index 8d669a4521..1496690d03 100644 --- a/modules/s3/s3xml.py +++ b/modules/s3/s3xml.py @@ -275,6 +275,7 @@ def transform(self, tree, stylesheet_path, **args): except: e = sys.exc_info()[1] self.error = e + current.log.error(e) return None else: # Error parsing the XSL stylesheet diff --git a/modules/s3cfg.py b/modules/s3cfg.py index 3ca8c9684a..5c1601ac3b 100644 --- a/modules/s3cfg.py +++ b/modules/s3cfg.py @@ -2179,6 +2179,18 @@ def get_org_facility_types_hierarchical(self): """ return self.org.get("facility_types_hierarchical", False) + def get_org_organisation_types_hierarchical(self): + """ + Whether Organisation Types are Hierarchical or not + """ + return self.org.get("organisation_types_hierarchical", False) + + def get_org_organisation_types_multiple(self): + """ + Whether Organisation Types are Multiple or not + """ + return self.org.get("organisation_types_multiple", False) + def get_org_groups(self): """ Whether to support Organisation Groups or not diff --git a/modules/s3db/cap.py b/modules/s3db/cap.py index 20acf7dd3d..7b0fe6dd72 100644 --- a/modules/s3db/cap.py +++ b/modules/s3db/cap.py @@ -1332,6 +1332,8 @@ def func(form): # ============================================================================= def cap_gis_location_xml_post_parse(element, record): """ + UNUSED - done in XSLT + Convert CAP polygon representation to WKT; extract circle lat lon. Latitude and longitude in CAP are expressed as signed decimal values in coordinate pairs: @@ -1389,11 +1391,11 @@ def cap_gis_location_xml_post_parse(element, record): record.lat_max = bbox["lat_max"] record.lon_max = bbox["lon_max"] - return - # ============================================================================= def cap_gis_location_xml_post_render(element, record): """ + UNUSED - done in XSLT + Convert Eden WKT polygon (and eventually circle) representation to CAP format and provide them in the rendered s3xml. diff --git a/modules/s3db/event.py b/modules/s3db/event.py index 86a23d2251..ded5cb91f4 100644 --- a/modules/s3db/event.py +++ b/modules/s3db/event.py @@ -271,9 +271,9 @@ def model(self): filter_widgets = [S3OptionsFilter("event_type_id", label = T("Type"), multiple = False, - options = lambda: \ - get_s3_filter_opts("event_event_type", - translate = True) + #options = lambda: \ + # get_s3_filter_opts("event_event_type", + # translate = True) ), ] diff --git a/modules/s3db/org.py b/modules/s3db/org.py index c93f3e455a..673b4ad366 100644 --- a/modules/s3db/org.py +++ b/modules/s3db/org.py @@ -97,6 +97,7 @@ class S3OrganisationModel(S3Model): "org_region", "org_organisation", "org_organisation_id", + "org_organisation_organisation_type", "org_organisation_user", "org_organisation_represent", ] @@ -115,52 +116,98 @@ def model(self): define_table = self.define_table NONE = messages["NONE"] + hierarchical_organisation_types = settings.get_org_organisation_types_hierarchical() + multiple_organisation_types = settings.get_org_organisation_types_multiple() + # --------------------------------------------------------------------- # Organisation Types # tablename = "org_organisation_type" define_table(tablename, Field("name", length=128, notnull=True, unique=True, - label=T("Name")), + label = T("Name"), + ), + Field("parent", "reference org_organisation_type", # This form of hierarchy may not work on all Databases + label = T("SubType of"), + ondelete = "RESTRICT", + readable = hierarchical_organisation_types, + writable = hierarchical_organisation_types, + ), s3_comments(), *s3_meta_fields()) + type_represent = S3Represent(lookup=tablename, translate=True) + + if hierarchical_organisation_types: + hierarchy = "parent" + # Can't be defined in-line as otherwise get a circular reference + table = db[tablename] + table.parent.represent = type_represent + table.parent.requires = IS_EMPTY_OR( + IS_ONE_OF(db, "org_organisation_type.id", + type_represent, + # If limiting to just 1 level of parent + #filterby="parent", + #filter_opts=(None,), + orderby="org_organisation_type.name")) + organisation_type_widget = S3HierarchyWidget(lookup = "org_organisation_type", + represent = type_represent, + multiple = multiple_organisation_types, + #leafonly = True, + ) + type_filter = S3HierarchyFilter("organisation_organisation_type.organisation_type_id", + label = T("Type"), + #multiple = multiple_organisation_types, + ) + type_widget = "hierarchy" + else: + hierarchy = None + organisation_type_widget = None + type_filter = S3OptionsFilter("organisation_organisation_type.organisation_type_id", + label = T("Type"), + #multiple = multiple_organisation_types, + ) + type_widget = "multiselect" + # CRUD strings crud_strings[tablename] = Storage( - label_create=T("Create Organization Type"), - title_display=T("Organization Type Details"), - title_list=T("Organization Types"), - title_update=T("Edit Organization Type"), - label_list_button=T("List Organization Types"), - label_delete_button=T("Delete Organization Type"), - msg_record_created=T("Organization Type added"), - msg_record_modified=T("Organization Type updated"), - msg_record_deleted=T("Organization Type deleted"), - msg_list_empty=T("No Organization Types currently registered")) + label_create = T("Create Organization Type"), + title_display = T("Organization Type Details"), + title_list = T("Organization Types"), + title_update = T("Edit Organization Type"), + label_list_button = T("List Organization Types"), + label_delete_button = T("Delete Organization Type"), + msg_record_created = T("Organization Type added"), + msg_record_modified = T("Organization Type updated"), + msg_record_deleted = T("Organization Type deleted"), + msg_list_empty = T("No Organization Types currently registered")) - represent = S3Represent(lookup=tablename, translate=True) organisation_type_id = S3ReusableField("organisation_type_id", - "reference %s" % tablename, - sortby="name", - requires=IS_EMPTY_OR( - IS_ONE_OF(db, - "org_organisation_type.id", - represent, - sort=True - )), - represent=represent, - label=T("Organization Type"), - comment=S3AddResourceLink(c="org", - f="organisation_type", - label=T("Create Organization Type"), - title=T("Organization Type"), - tooltip=T("If you don't see the Type in the list, you can add a new one by clicking link 'Create Organization Type'.")), - ondelete="SET NULL") + "reference %s" % tablename, + label = T("Organization Type"), + ondelete = "SET NULL", + represent = type_represent, + requires = IS_EMPTY_OR( + IS_ONE_OF(db, + "org_organisation_type.id", + type_represent, + sort = True + )), + sortby = "name", + widget = organisation_type_widget, + comment = S3AddResourceLink(c="org", + f="organisation_type", + label=T("Create Organization Type"), + title=T("Organization Type"), + tooltip=T("If you don't see the Type in the list, you can add a new one by clicking link 'Create Organization Type'.") + ), + ) configure(tablename, # Not needed since unique=True but would be # if we removed to make these variable by Org - #deduplicate=self.organisation_type_duplicate, + #deduplicate = self.organisation_type_duplicate, + hierarchy = hierarchy, ) # Components @@ -214,20 +261,22 @@ def model(self): # CRUD strings crud_strings[tablename] = Storage( - label_create=T("Add Region"), - title_display=T("Region Details"), - title_list=T("Regions"), - title_update=T("Edit Region"), - label_list_button=T("List Regions"), - label_delete_button=T("Delete Region"), - msg_record_created=T("Region added"), - msg_record_modified=T("Region updated"), - msg_record_deleted=T("Region deleted"), - msg_list_empty=T("No Regions currently registered")) + label_create = T("Add Region"), + title_display = T("Region Details"), + title_list = T("Regions"), + title_update = T("Edit Region"), + label_list_button = T("List Regions"), + label_delete_button = T("Delete Region"), + msg_record_created = T("Region added"), + msg_record_modified = T("Region updated"), + msg_record_deleted = T("Region deleted"), + msg_list_empty = T("No Regions currently registered")) region_id = S3ReusableField("region_id", "reference %s" % tablename, - sortby="name", - requires=IS_EMPTY_OR( + label = T("Region"), + ondelete = "SET NULL", + represent = region_represent, + requires = IS_EMPTY_OR( IS_ONE_OF(db, "org_region.id", region_represent, sort=True, @@ -235,14 +284,14 @@ def model(self): not_filterby="parent", not_filter_opts=(None,) )), - represent=region_represent, - label=T("Region"), - comment=S3AddResourceLink(c="org", - f="region", - label=T("Add Region"), - title=T("Region"), - tooltip=T("If you don't see the Type in the list, you can add a new one by clicking link 'Add Region'.")), - ondelete="SET NULL") + sortby = "name", + comment = S3AddResourceLink(c="org", + f="region", + label=T("Add Region"), + title=T("Region"), + tooltip=T("If you don't see the Type in the list, you can add a new one by clicking link 'Add Region'.") + ), + ) configure(tablename, deduplicate = self.org_region_duplicate, @@ -268,63 +317,59 @@ def model(self): ), Field("name", notnull=True, unique=True, length=128, # Mayon Compatibility - label=T("Name")), + label = T("Name"), + ), # http://hxl.humanitarianresponse.info/#abbreviation Field("acronym", length=16, - label=T("Acronym"), - represent=lambda val: val or "", - comment=DIV(_class="tooltip", - _title="%s|%s" % (T("Acronym"), - T("Acronym of the organization's name, eg. IFRC.")))), - organisation_type_id(#readable = False, - #writable = False, - ), - #Field("registration", label=T("Registration")), # Registration Number + label = T("Acronym"), + represent = lambda val: val or "", + comment = DIV(_class="tooltip", + _title="%s|%s" % (T("Acronym"), + T("Acronym of the organization's name, eg. IFRC."))) + ), + #Field("registration", label = T("Registration")), # Registration Number region_id(), Field("country", length=2, - label=T("Home Country"), - #readable = False, - #writable = False, - requires=IS_EMPTY_OR(IS_IN_SET_LAZY( + label = T("Home Country"), + represent = self.gis_country_code_represent, + requires = IS_EMPTY_OR(IS_IN_SET_LAZY( lambda: gis.get_countries(key_type="code"), zero=messages.SELECT_LOCATION)), - represent=self.gis_country_code_represent, ), # @ToDo: Deprecate with Contact component Field("phone", - label=T("Phone #"), + label = T("Phone #"), + represent = lambda v: v or NONE, + requires = IS_EMPTY_OR(s3_phone_requires), #readable = False, #writable = False, - requires=IS_EMPTY_OR(s3_phone_requires), - represent=lambda v: v or NONE ), # http://hxl.humanitarianresponse.info/#organisationHomepage Field("website", - label=T("Website"), - requires=IS_EMPTY_OR(IS_URL()), - represent=s3_url_represent), + label = T("Website"), + represent = s3_url_represent, + requires = IS_EMPTY_OR(IS_URL()), + ), Field("year", "integer", - label=T("Year"), - #readable = False, - #writable = False, - requires=IS_EMPTY_OR( - IS_INT_IN_RANGE(1850, 2100)), - represent=lambda v: v or NONE, - comment=DIV(_class="tooltip", - _title="%s|%s" % (T("Year"), - T("Year that the organization was founded"))), + label = T("Year"), + represent = lambda v: v or NONE, + requires = IS_EMPTY_OR( + IS_INT_IN_RANGE(1850, 2100)), + comment = DIV(_class="tooltip", + _title="%s|%s" % (T("Year"), + T("Year that the organization was founded"))), ), Field("logo", "upload", - label=T("Logo"), + label = T("Logo"), + represent = self.doc_image_represent, + requires = [IS_EMPTY_OR(IS_IMAGE(maxsize=(400, 400), + error_message=T("Upload an image file (png or jpeg), max. 400x400 pixels!"))), + IS_EMPTY_OR(IS_UPLOAD_FILENAME())], + comment = DIV(_class="tooltip", + _title="%s|%s" % (T("Logo"), + T("Logo of the organization. This should be a png or jpeg file and it should be no larger than 400x400"))), uploadfolder = os.path.join( - current.request.folder, "uploads"), - requires=[IS_EMPTY_OR(IS_IMAGE(maxsize=(400, 400), - error_message=T("Upload an image file (png or jpeg), max. 400x400 pixels!"))), - IS_EMPTY_OR(IS_UPLOAD_FILENAME())], - represent=self.doc_image_represent, - comment=DIV(_class="tooltip", - _title="%s|%s" % (T("Logo"), - T("Logo of the organization. This should be a png or jpeg file and it should be no larger than 400x400"))) + current.request.folder, "uploads"), ), s3_comments(), #document_id(), # Better to have multiple Documents on a Tab @@ -332,20 +377,38 @@ def model(self): #Field("archived", "boolean", default=False), *s3_meta_fields()) + crud_form = S3SQLCustomForm("name", + "acronym", + S3SQLInlineLink( + "organisation_type", + field = "organisation_type_id", + label = T("Type"), + multiple = multiple_organisation_types, + widget = type_widget, + ), + "region_id", + "country", + "phone", + "website", + "year", + "logo", + "comments", + ) + # CRUD strings ADD_ORGANIZATION = T("Create Organization") crud_strings[tablename] = Storage( - label_create=T("Create Organization"), - title_display=T("Organization Details"), - title_list=T("Organizations"), - title_update=T("Edit Organization"), - title_upload=T("Import Organizations"), - label_list_button=T("List Organizations"), - label_delete_button=T("Delete Organization"), - msg_record_created=T("Organization added"), - msg_record_modified=T("Organization updated"), - msg_record_deleted=T("Organization deleted"), - msg_list_empty=T("No Organizations currently registered")) + label_create = T("Create Organization"), + title_display = T("Organization Details"), + title_list = T("Organizations"), + title_update = T("Edit Organization"), + title_upload = T("Import Organizations"), + label_list_button = T("List Organizations"), + label_delete_button = T("Delete Organization"), + msg_record_created = T("Organization added"), + msg_record_modified = T("Organization updated"), + msg_record_deleted = T("Organization deleted"), + msg_list_empty = T("No Organizations currently registered")) if settings.get_org_autocomplete(): help = messages.AUTOCOMPLETE_HELP @@ -400,9 +463,7 @@ def model(self): #_class = "filter-search", ), # NB Order is important here - gets popped in asset & inv controllers & IFRC template - S3OptionsFilter("organisation_type_id", - label = T("Type"), - ), + type_filter, # NB Order is important here - gets popped in asset & inv controllers & IFRC template S3OptionsFilter("sector_organisation.sector_id", options = lambda: \ @@ -420,12 +481,13 @@ def model(self): configure(tablename, context = {"location": "site.location_id", }, + crud_form = crud_form, deduplicate = self.organisation_duplicate, filter_widgets = filter_widgets, list_fields = ["id", "name", "acronym", - "organisation_type_id", + "organisation_organisation_type.organisation_type_id", "website" ], list_layout = org_organisation_list_layout, @@ -434,7 +496,6 @@ def model(self): ondelete = self.org_organisation_ondelete, referenced_by = [(utablename, "organisation_id")], super_entity = "pr_pentity", - xml_post_parse = self.org_organisation_xml_post_parse, ) # Custom Method for S3OrganisationAutocompleteWidget @@ -475,6 +536,15 @@ def model(self): }, # Format for filter_widget org_organisation_location = "organisation_id", + # Types + org_organisation_type = {"link": "org_organisation_organisation_type", + "joinby": "organisation_id", + "key": "organisation_type_id", + "multiple": multiple_organisation_types, + "actuate": "hide", + }, + # Format for filter_widget + org_organisation_organisation_type = "organisation_id", # Catalogs supply_catalog = "organisation_id", # Resources @@ -564,6 +634,23 @@ def model(self): }, ) + # --------------------------------------------------------------------- + # Organisation <-> Organisation Type + # + tablename = "org_organisation_organisation_type" + define_table(tablename, + organisation_id(empty = False, + ondelete = "CASCADE", + ), + organisation_type_id(empty = False, + ondelete = "CASCADE", + ), + *s3_meta_fields()) + + configure(tablename, + xml_post_parse = self.org_organisation_organisation_type_xml_post_parse, + ) + # --------------------------------------------------------------------- # Organisation <-> User # @@ -571,16 +658,18 @@ def model(self): tablename = "org_organisation_user" define_table(tablename, Field("user_id", utable), - organisation_id(), + organisation_id(empty = False, + ondelete = "CASCADE", + ), *s3_meta_fields()) # --------------------------------------------------------------------- # Pass names back to global scope (s3.*) # - return dict(org_organisation_type_id=organisation_type_id, - org_organisation_id=organisation_id, - org_organisation_represent=org_organisation_represent, - org_region_represent=region_represent, + return dict(org_organisation_type_id = organisation_type_id, + org_organisation_id = organisation_id, + org_organisation_represent = org_organisation_represent, + org_region_represent = region_represent, ) # ------------------------------------------------------------------------- @@ -670,7 +759,7 @@ def org_organisation_ondelete(row): # ------------------------------------------------------------------------- @staticmethod - def org_organisation_xml_post_parse(element, record): + def org_organisation_organisation_type_xml_post_parse(element, record): """ Check for defaults provided by project/organisation.xsl """ @@ -680,27 +769,25 @@ def org_organisation_xml_post_parse(element, record): org_type_default = org_type_default[0].text db = current.db table = db.org_organisation_type - cache = current.s3db.cache row = None # These default mappings can be overridden per-deployment if org_type_default == "Donor": row = db(table.name == "Bilateral").select(table.id, - cache=cache, + cache=current.s3db.cache, limitby=(0, 1)).first() elif org_type_default == "Partner": row = db(table.name == "NGO").select(table.id, - cache=cache, + cache=current.s3db.cache, limitby=(0, 1)).first() elif org_type_default in ("Host National Society", "Partner National Society"): row = db(table.name == "Red Cross / Red Crescent").select(table.id, - cache=cache, + cache=current.s3db.cache, limitby=(0, 1) ).first() if row: # Note this sets only the default, so won't override existing or explicit values record._organisation_type_id = row.id - return # ------------------------------------------------------------------------- @staticmethod @@ -899,23 +986,23 @@ def model(self): # CRUD strings current.response.s3.crud_strings[tablename] = Storage( - label_create=T("Add Branch Organization"), - title_display=T("Branch Organization Details"), - title_list=T("Branch Organizations"), - title_update=T("Edit Branch Organization"), - #title_upload=T("Import Branch Organizations"), - label_list_button=T("List Branch Organizations"), - label_delete_button=T("Delete Branch"), - msg_record_created=T("Branch Organization added"), - msg_record_modified=T("Branch Organization updated"), - msg_record_deleted=T("Branch Organization deleted"), - msg_list_empty=T("No Branch Organizations currently registered")) + label_create = T("Add Branch Organization"), + title_display = T("Branch Organization Details"), + title_list = T("Branch Organizations"), + title_update = T("Edit Branch Organization"), + #title_upload = T("Import Branch Organizations"), + label_list_button = T("List Branch Organizations"), + label_delete_button = T("Delete Branch"), + msg_record_created = T("Branch Organization added"), + msg_record_modified = T("Branch Organization updated"), + msg_record_deleted = T("Branch Organization deleted"), + msg_list_empty = T("No Branch Organizations currently registered")) self.configure(tablename, deduplicate = self.org_branch_duplicate, onaccept = self.org_branch_onaccept, - ondelete=self.org_branch_ondelete, - onvalidation=self.org_branch_onvalidation, + ondelete = self.org_branch_ondelete, + onvalidation = self.org_branch_onvalidation, ) # ----------------------------------------------------------------------------- @@ -944,10 +1031,10 @@ def org_branch_onvalidation(form): - this is for interactive forms, imports are caught in .xsl """ - vars = form.request_vars - if vars and \ - vars.branch_id and \ - int(vars.branch_id) == int(vars.organisation_id): + request_vars = form.request_vars + if request_vars and \ + request_vars.branch_id and \ + int(request_vars.branch_id) == int(request_vars.organisation_id): error = current.T("Cannot make an Organization a branch of itself!") form.errors["branch_id"] = error current.response.error = error @@ -959,15 +1046,13 @@ def org_branch_onaccept(form): Remove any duplicate memberships and update affiliations """ - id = form.vars.id + _id = form.vars.id db = current.db s3db = current.s3db # Fields a branch organisation inherits from its parent organisation - inherit = ["organisation_type_id", - # @ToDo: Update for Component - #"sector", - "region_id", + # (components added later) + inherit = ["region_id", "country", ] @@ -981,16 +1066,15 @@ def org_branch_onaccept(form): left = [otable.on(ltable.organisation_id == otable.id), btable.on(ltable.branch_id == btable.id)] - record = db(ltable.id == id).select( - otable.root_organisation, - btable.root_organisation, - ltable.branch_id, - ltable.organisation_id, - ltable.deleted, - ltable.deleted_fk, - *ifields, - left=left, - limitby=(0, 1)).first() + record = db(ltable.id == _id).select(otable.root_organisation, + btable.root_organisation, + ltable.branch_id, + ltable.organisation_id, + ltable.deleted, + ltable.deleted_fk, + *ifields, + left=left, + limitby=(0, 1)).first() if record: organisation = record.org_organisation @@ -1010,10 +1094,44 @@ def org_branch_onaccept(form): if update: db(otable.id == branch_id).update(**update) + # Org Types + ltable = db.org_organisation_organisation_type + rows = db(ltable.organisation_id.belongs((organisation_id, branch_id))).select(ltable.organisation_id, + ltable.organisation_type_id) + org_types = [] + branch_types = [] + for row in rows: + if row.organisation_id == organisation_id: + org_types.append(row.organisation_type_id) + else: + branch_types.append(row.organisation_type_id) + for t in org_types: + if t not in branch_types: + ltable.insert(organisation_id = branch_id, + organisation_type_id = t, + ) + + # Sectors + ltable = s3db.org_sector_organisation + rows = db(ltable.organisation_id.belongs((organisation_id, branch_id))).select(ltable.organisation_id, + ltable.sector_id) + org_sectors = [] + branch_sectors = [] + for row in rows: + if row.organisation_id == organisation_id: + org_sectors.append(row.sector_id) + else: + branch_sectors.append(row.sector_id) + for s in org_sectors: + if s not in branch_sectors: + ltable.insert(organisation_id = branch_id, + sector_id = s, + ) + # Eliminate duplicate affiliations query = (ltable.branch_id == branch_id) & \ (ltable.organisation_id == organisation_id) & \ - (ltable.id != id) & \ + (ltable.id != _id) & \ (ltable.deleted != True) deleted_fk = {"branch_id": branch_id, @@ -1033,8 +1151,6 @@ def org_branch_onaccept(form): branch.root_organisation != organisation.root_organisation: org_update_root_organisation(branch_id) - return - # ------------------------------------------------------------------------- @staticmethod def org_branch_ondelete(row): @@ -1050,7 +1166,6 @@ def org_branch_ondelete(row): limitby=(0, 1)).first() if record: org_update_affiliations("org_organisation_branch", record) - return # ============================================================================= class S3OrganisationGroupModel(S3Model): @@ -1265,7 +1380,6 @@ def group_membership_onaccept(form): group_id = None, deleted_fk = json.dumps(deleted_fk)) org_update_affiliations("org_group_membership", record) - return # ============================================================================= class S3OrganisationGroupPersonModel(S3Model): @@ -1357,7 +1471,6 @@ def org_group_team_onaccept(form): current.s3db.pr_add_affiliation(org_group, pr_group, role="Groups", role_type=1) # 1 = OU - return # ============================================================================= class S3OrganisationLocationModel(S3Model): @@ -1428,8 +1541,6 @@ def org_organisation_location_deduplicate(item): item.id = duplicate.id item.method = item.METHOD.UPDATE - return - # ============================================================================= class S3OrganisationResourceModel(S3Model): """ @@ -1461,7 +1572,7 @@ def model(self): self.define_table(tablename, super_link("parameter_id", "stats_parameter"), Field("name", - label=T("Resource Type"), + label = T("Resource Type"), ), s3_comments(), *s3_meta_fields()) @@ -1469,17 +1580,17 @@ def model(self): # CRUD strings ADD_RESOURCE_TYPE = T("Add New Resource Type") crud_strings[tablename] = Storage( - label_create=T("Add Resource Type"), - title_display=T("Resource Type Details"), - title_list=T("Resource Types"), - title_update=T("Edit Resource Type"), - title_upload=T("Import Resource Types"), - label_list_button=T("Resource Types"), - label_delete_button=T("Delete Resource Type"), - msg_record_created=T("Resource Type added"), - msg_record_modified=T("Resource Type updated"), - msg_record_deleted=T("Resource Type deleted"), - msg_list_empty=T("No Resource Types defined")) + label_create = T("Add Resource Type"), + title_display = T("Resource Type Details"), + title_list = T("Resource Types"), + title_update = T("Edit Resource Type"), + title_upload = T("Import Resource Types"), + label_list_button = T("Resource Types"), + label_delete_button = T("Delete Resource Type"), + msg_record_created = T("Resource Type added"), + msg_record_modified = T("Resource Type updated"), + msg_record_deleted = T("Resource Type deleted"), + msg_list_empty = T("No Resource Types defined")) # Resource Configuration configure(tablename, @@ -1532,18 +1643,18 @@ def model(self): # CRUD strings crud_strings[tablename] = Storage( - label_create=T("Create Resource"), - title_display=T("Resource Details"), - title_list=T("Resource Inventory"), - title_update=T("Edit Resource"), - title_map=T("Map of Resources"), - title_upload=T("Import Resources"), - label_list_button=T("Resource Inventory"), - label_delete_button=T("Delete Resource"), - msg_record_created=T("Resource added"), - msg_record_modified=T("Resource updated"), - msg_record_deleted=T("Resource deleted"), - msg_list_empty=T("No Resources in Inventory")) + label_create = T("Create Resource"), + title_display = T("Resource Details"), + title_list = T("Resource Inventory"), + title_update = T("Edit Resource"), + title_map = T("Map of Resources"), + title_upload = T("Import Resources"), + label_list_button = T("Resource Inventory"), + label_delete_button = T("Delete Resource"), + msg_record_created = T("Resource added"), + msg_record_modified = T("Resource updated"), + msg_record_deleted = T("Resource deleted"), + msg_list_empty = T("No Resources in Inventory")) # Filter Widgets filter_widgets = [S3TextFilter(["organisation_id$name", @@ -1627,19 +1738,17 @@ def model(self): # tablename = "org_sector" define_table(tablename, - Field("name", - length=128, - notnull=True, - label=T("Name"), - represent=lambda v: T(v) if v is not None \ + Field("name", length=128, notnull=True, + label = T("Name"), + represent = lambda v: T(v) if v is not None \ else NONE, ), - Field("abrv", length=64, - #notnull=True, - label=T("Abbreviation")), + Field("abrv", length=64, #notnull=True, + label = T("Abbreviation"), + ), self.gis_location_id( - widget=S3LocationAutocompleteWidget(), - requires=IS_EMPTY_OR(IS_LOCATION()) + requires = IS_EMPTY_OR(IS_LOCATION()), + widget = S3LocationAutocompleteWidget(), ), s3_comments(), *s3_meta_fields()) @@ -1650,35 +1759,35 @@ def model(self): ADD_SECTOR = T("Create Cluster") help = T("If you don't see the Cluster in the list, you can add a new one by clicking link 'Add New Cluster'.") crud_strings[tablename] = Storage( - label_create=ADD_SECTOR, - title_display=T("Cluster Details"), - title_list=T("Clusters"), - title_update=T("Edit Cluster"), - label_list_button=T("List Clusters"), - label_delete_button=T("Delete Cluster"), - msg_record_created=T("Cluster added"), - msg_record_modified=T("Cluster updated"), - msg_record_deleted=T("Cluster deleted"), - msg_list_empty=T("No Clusters currently registered")) + label_create = ADD_SECTOR, + title_display = T("Cluster Details"), + title_list = T("Clusters"), + title_update = T("Edit Cluster"), + label_list_button = T("List Clusters"), + label_delete_button = T("Delete Cluster"), + msg_record_created = T("Cluster added"), + msg_record_modified = T("Cluster updated"), + msg_record_deleted = T("Cluster deleted"), + msg_list_empty = T("No Clusters currently registered")) else: SECTOR = T("Sector") ADD_SECTOR = T("Create Sector") help = T("If you don't see the Sector in the list, you can add a new one by clicking link 'Create Sector'.") crud_strings[tablename] = Storage( - label_create=ADD_SECTOR, - title_display=T("Sector Details"), - title_list=T("Sectors"), - title_update=T("Edit Sector"), - label_list_button=T("List Sectors"), - label_delete_button=T("Delete Sector"), - msg_record_created=T("Sector added"), - msg_record_modified=T("Sector updated"), - msg_record_deleted=T("Sector deleted"), - msg_list_empty=T("No Sectors currently registered")) + label_create = ADD_SECTOR, + title_display = T("Sector Details"), + title_list = T("Sectors"), + title_update = T("Edit Sector"), + label_list_button = T("List Sectors"), + label_delete_button = T("Delete Sector"), + msg_record_created = T("Sector added"), + msg_record_modified = T("Sector updated"), + msg_record_deleted = T("Sector deleted"), + msg_list_empty = T("No Sectors currently registered")) configure("org_sector", - deduplicate=self.org_sector_duplicate, - onaccept=self.org_sector_onaccept, + deduplicate = self.org_sector_duplicate, + onaccept = self.org_sector_onaccept, ) sector_comment = lambda child: S3AddResourceLink(c="org", f="sector", @@ -1689,56 +1798,57 @@ def model(self): represent = S3Represent(lookup=tablename, translate=True) sector_id = S3ReusableField("sector_id", "reference %s" % tablename, - sortby="abrv", - requires=IS_EMPTY_OR( + label = SECTOR, + ondelete = "SET NULL", + represent = represent, + requires = IS_EMPTY_OR( IS_ONE_OF(db, "org_sector.id", represent, sort=True, filterby=filterby, filter_opts=filter_opts, )), - represent=represent, - comment=sector_comment("sector_id"), - label=SECTOR, - ondelete="SET NULL") + sortby = "abrv", + comment = sector_comment("sector_id"), + ) # Components add_components(tablename, - org_organisation={"link": "org_sector_organisation", - "joinby": "sector_id", - "key": "organisation_id", - "actuate": "hide", - }, - project_project={"link": "project_sector_project", - "joinby": "sector_id", - "key": "project_id", - "actuate": "hide", - }, - #project_activity_type={"link": "project_activity_type_sector", - # "joinby": "sector_id", - # "key": "activity_type_id", - # "actuate": "hide", - # }, - #project_theme={"link": "project_theme_sector", - # "joinby": "sector_id", - # "key": "theme_id", - # "actuate": "hide", - # }, - #org_subsector="sector_id", - ) + org_organisation = {"link": "org_sector_organisation", + "joinby": "sector_id", + "key": "organisation_id", + "actuate": "hide", + }, + project_project = {"link": "project_sector_project", + "joinby": "sector_id", + "key": "project_id", + "actuate": "hide", + }, + #project_activity_type = {"link": "project_activity_type_sector", + # "joinby": "sector_id", + # "key": "activity_type_id", + # "actuate": "hide", + # }, + #project_theme = {"link": "project_theme_sector", + # "joinby": "sector_id", + # "key": "theme_id", + # "actuate": "hide", + # }, + #org_subsector = "sector_id", + ) # ===================================================================== # (Cluster) Subsector # # tablename = "org_subsector" # define_table(tablename, - # sector_id(), - # Field("name", length=128, - # label=T("Name")), - # Field("abrv", length=64, - # notnull=True, unique=True, - # label=T("Abbreviation")), - # *s3_meta_fields()) + # sector_id(), + # Field("name", length=128, + # label = T("Name")), + # Field("abrv", length=64, + # notnull=True, unique=True, + # label = T("Abbreviation")), + # *s3_meta_fields()) ##CRUD strings # if settings.get_ui_label_cluster(): @@ -1769,15 +1879,16 @@ def model(self): # msg_list_empty = T("No Subsectors currently registered")) # subsector_id = S3ReusableField("subsector_id", "reference %s" % tablename, - # sortby="abrv", - # requires = IS_EMPTY_OR( - # IS_ONE_OF(db, "org_subsector.id", - # self.org_subsector_represent, - # sort=True)), - # represent = self.org_subsector_represent, - # label = SUBSECTOR, - ##comment = Script to filter the sector_subsector drop down - # ondelete = "SET NULL") + # label = SUBSECTOR, + # ondelete = "SET NULL", + # represent = self.org_subsector_represent, + # requires = IS_EMPTY_OR( + # IS_ONE_OF(db, "org_subsector.id", + # self.org_subsector_represent, + # sort=True)), + # sortby="abrv", + # #comment = Script to filter the sector_subsector drop down + # ) # configure("org_subsector", deduplicate=self.org_sector_duplicate) @@ -1793,7 +1904,7 @@ def model(self): # CRUD Strings crud_strings[tablename] = Storage( - label_create = T("New Sector"), + label_create = T("Create Sector"), title_display = T("Sector"), title_list = T("Sectors"), title_update = T("Edit Sector"), @@ -1838,41 +1949,43 @@ def org_sector_duplicate(item): def org_sector_onaccept(form): """ If no abrv is set then set it from the name """ - id = form.vars.id + _id = form.vars.id # Read the record db = current.db table = db.org_sector - record = db(table.id == id).select(table.abrv, - table.name, - limitby=(0, 1)).first() + record = db(table.id == _id).select(table.abrv, + table.name, + limitby=(0, 1)).first() if not record.abrv: - db(table.id == id).update(abrv = record.name[:64]) + db(table.id == _id).update(abrv = record.name[:64]) # ------------------------------------------------------------------------- - @staticmethod - def org_subsector_represent(id, row=None): - """ Subsector ID representation """ - - if row: - return row.name - elif not id: - return current.messages["NONE"] - - db = current.db - table = db.org_subsector - r = db(table.id == id).select(table.name, - table.sector_id, - limitby=(0, 1)).first() - try: - sector = db(query).select(table.abrv, - limitby=(0, 1)).first() - if sector: - return "%s: %s" % (sector.abrv, current.T(r.name)) - else: - return current.T(r.name) - except: - return current.messages.UNKNOWN_OPT + #@staticmethod + #def org_subsector_represent(id, row=None): + # """ Subsector ID representation """ + + # if row: + # return row.name + # elif not id: + # return current.messages["NONE"] + + # db = current.db + # table = db.org_subsector + # r = db(table.id == id).select(table.name, + # table.sector_id, + # limitby=(0, 1) + # ).first() + # try: + # sector = db(table.id == r.sector_id).select(table.abrv, + # limitby=(0, 1) + # ).first() + # if sector: + # return "%s: %s" % (sector.abrv, current.T(r.name)) + # else: + # return current.T(r.name) + # except: + # return current.messages.UNKNOWN_OPT # ------------------------------------------------------------------------- @staticmethod @@ -1969,14 +2082,14 @@ def model(self): # Reusable Field service_id = S3ReusableField("service_id", "reference %s" % tablename, - sortby = "name", label = T("Services"), + ondelete = "CASCADE", + represent = represent, requires = IS_EMPTY_OR( IS_ONE_OF(db, "org_service.id", represent, sort=True)), - represent = represent, - ondelete = "CASCADE", + sortby = "name", ) configure(tablename, @@ -2036,8 +2149,6 @@ def org_service_organisation_deduplicate(item): item.id = duplicate.id item.method = item.METHOD.UPDATE - return - # ============================================================================= class S3OrganisationSummaryModel(S3Model): """ @@ -2059,11 +2170,13 @@ def model(self): self.define_table(tablename, self.org_organisation_id(ondelete="CASCADE"), Field("national_staff", "integer", # national is a reserved word in Postgres - requires=IS_EMPTY_OR(IS_INT_IN_RANGE(0, 9999)), - label=T("# of National Staff")), + label = T("# of National Staff"), + requires = IS_EMPTY_OR(IS_INT_IN_RANGE(0, 9999)), + ), Field("international_staff", "integer", - requires=IS_EMPTY_OR(IS_INT_IN_RANGE(0, 9999)), - label=T("# of International Staff")), + label = T("# of International Staff"), + requires = IS_EMPTY_OR(IS_INT_IN_RANGE(0, 9999)), + ), *s3_meta_fields()) # Pass names back to global scope (s3.*) @@ -2079,8 +2192,6 @@ class S3OrganisationTeamModel(S3Model): def model(self): - T = current.T - # --------------------------------------------------------------------- # Link table between Organisations & Teams # @@ -2130,7 +2241,6 @@ def org_team_onaccept(form): current.s3db.pr_add_affiliation(org, group, role="Groups", role_type=1) # 1 = OU - return # ============================================================================= class S3OrganisationTypeTagModel(S3Model): @@ -2158,8 +2268,12 @@ def model(self): self.define_table(tablename, self.org_organisation_type_id(), # key is a reserved word in MySQL - Field("tag", label=T("Key")), - Field("value", label=T("Value")), + Field("tag", + label = T("Key"), + ), + Field("value", + label = T("Value"), + ), s3_comments(), *s3_meta_fields()) @@ -2784,34 +2898,34 @@ def model(self): # @ToDo: Flexible Labelling: 'Facility, 'Place', 'Site' ADD_FAC = T("Create Facility Type") crud_strings[tablename] = Storage( - label_create=ADD_FAC, - title_display=T("Facility Type Details"), - title_list=T("Facility Types"), - title_update=T("Edit Facility Type"), - title_upload=T("Import Facility Types"), - label_list_button=T("List Facility Types"), - label_delete_button=T("Delete Facility Type"), - msg_record_created=T("Facility Type added"), - msg_record_modified=T("Facility Type updated"), - msg_record_deleted=T("Facility Type deleted"), - msg_list_empty=T("No Facility Types currently registered")) + label_create = ADD_FAC, + title_display = T("Facility Type Details"), + title_list = T("Facility Types"), + title_update = T("Edit Facility Type"), + title_upload = T("Import Facility Types"), + label_list_button = T("List Facility Types"), + label_delete_button = T("Delete Facility Type"), + msg_record_created = T("Facility Type added"), + msg_record_modified = T("Facility Type updated"), + msg_record_deleted = T("Facility Type deleted"), + msg_list_empty = T("No Facility Types currently registered")) facility_type_id = S3ReusableField("facility_type_id", "reference %s" % tablename, - sortby = "name", + label = T("Facility Type"), + ondelete = "CASCADE", + represent = type_represent, # Only used by org_site_facility_type requires = IS_ONE_OF(db, "org_facility_type.id", type_represent, sort = True, ), - represent = type_represent, - label = T("Facility Type"), + sortby = "name", comment = S3AddResourceLink(c = "org", f = "facility_type", label = ADD_FAC, title = T("Facility Type"), tooltip = T("If you don't see the Type in the list, you can add a new one by clicking link 'Create Facility Type'.")), - ondelete = "CASCADE", ) configure(tablename, @@ -2848,22 +2962,23 @@ def model(self): represent = lambda v: v or NONE, ), Field("contact", + label = T("Contact"), represent = lambda v: v or NONE, - label=T("Contact")), + ), Field("phone1", label = T("Phone 1"), - requires=IS_EMPTY_OR(s3_phone_requires), represent = lambda v: v or NONE, + requires=IS_EMPTY_OR(s3_phone_requires), ), Field("phone2", label = T("Phone 2"), - requires = IS_EMPTY_OR(s3_phone_requires), represent = lambda v: v or NONE, + requires = IS_EMPTY_OR(s3_phone_requires), ), Field("email", label = T("Email"), - requires = IS_EMPTY_OR(IS_EMAIL()), represent = lambda v: v or NONE, + requires = IS_EMPTY_OR(IS_EMAIL()), ), Field("website", label = T("Website"), @@ -2886,18 +3001,18 @@ def model(self): # CRUD strings ADD_FAC = T("Create Facility") crud_strings[tablename] = Storage( - label_create=ADD_FAC, - title_display=T("Facility Details"), - title_list=T("Facilities"), - title_update=T("Edit Facility"), - title_map=T("Map of Facilities"), - title_upload=T("Import Facilities"), - label_list_button=T("List Facilities"), - label_delete_button=T("Delete Facility"), - msg_record_created=T("Facility added"), - msg_record_modified=T("Facility updated"), - msg_record_deleted=T("Facility deleted"), - msg_list_empty=T("No Facilities currently registered")) + label_create = ADD_FAC, + title_display = T("Facility Details"), + title_list = T("Facilities"), + title_update = T("Edit Facility"), + title_map = T("Map of Facilities"), + title_upload = T("Import Facilities"), + label_list_button = T("List Facilities"), + label_delete_button = T("Delete Facility"), + msg_record_created = T("Facility added"), + msg_record_modified = T("Facility updated"), + msg_record_deleted = T("Facility deleted"), + msg_list_empty = T("No Facilities currently registered")) # Which levels of Hierarchy are we using? levels = current.gis.get_relevant_hierarchy_levels() @@ -2928,8 +3043,8 @@ def model(self): # @ToDo: Introspect need for header based on # records #header = True, label = T("Type"), - represent = "%(name)s", - widget = "multiselect", + # Doesn't support translation + #represent = "%(name)s", ) @@ -2944,14 +3059,12 @@ def model(self): #header = True, label = T("Organization"), represent = "%(name)s", - widget = "multiselect", ), S3LocationFilter("location_id", # @ToDo: Display by default in Summary Views but not others? #hidden = True, label = T("Location"), levels = levels, - widget = "multiselect", ), ] @@ -2963,7 +3076,6 @@ def model(self): # @ToDo: Introspect need for header based on # records #header = True, represent = "%(name)s", - widget = "multiselect", )) regions = settings.get_org_regions() @@ -3373,22 +3485,24 @@ def model(self): tablename = "org_room" self.define_table(tablename, self.org_site_id, # site_id - Field("name", length=128, notnull=True), + Field("name", length=128, notnull=True, + label = T("Name"), + ), *s3_meta_fields()) # CRUD strings ADD_ROOM = T("Create Room") current.response.s3.crud_strings[tablename] = Storage( - label_create=ADD_ROOM, - title_display=T("Room Details"), - title_list=T("Rooms"), - title_update=T("Edit Room"), - label_list_button=T("List Rooms"), - label_delete_button=T("Delete Room"), - msg_record_created=T("Room added"), - msg_record_modified=T("Room updated"), - msg_record_deleted=T("Room deleted"), - msg_list_empty=T("No Rooms currently registered")) + label_create = ADD_ROOM, + title_display = T("Room Details"), + title_list = T("Rooms"), + title_update = T("Edit Room"), + label_list_button = T("List Rooms"), + label_delete_button = T("Delete Room"), + msg_record_created = T("Room added"), + msg_record_modified = T("Room updated"), + msg_record_deleted = T("Room deleted"), + msg_list_empty = T("No Rooms currently registered")) room_comment = DIV( S3AddResourceLink(c="org", @@ -3408,15 +3522,15 @@ def model(self): # Reusable field for other tables to reference represent = S3Represent(lookup=tablename) room_id = S3ReusableField("room_id", "reference %s" % tablename, - sortby="name", - requires=IS_EMPTY_OR( - IS_ONE_OF(db, "org_room.id", - represent - )), - represent=represent, - label=T("Room"), - comment=room_comment, - ondelete="SET NULL" + label = T("Room"), + ondelete = "SET NULL", + represent = represent, + requires = IS_EMPTY_OR( + IS_ONE_OF(db, "org_room.id", + represent + )), + sortby = "name", + comment = room_comment, ) self.configure(tablename, @@ -3482,16 +3596,16 @@ def model(self): # CRUD strings ADD_OFFICE_TYPE = T("Create Office Type") crud_strings[tablename] = Storage( - label_create=T("Create Office Type"), - title_display=T("Office Type Details"), - title_list=T("Office Types"), - title_update=T("Edit Office Type"), - label_list_button=T("List Office Types"), - label_delete_button=T("Delete Office Type"), - msg_record_created=T("Office Type added"), - msg_record_modified=T("Office Type updated"), - msg_record_deleted=T("Office Type deleted"), - msg_list_empty=T("No Office Types currently registered")) + label_create = ADD_OFFICE_TYPE, + title_display = T("Office Type Details"), + title_list = T("Office Types"), + title_update = T("Edit Office Type"), + label_list_button = T("List Office Types"), + label_delete_button = T("Delete Office Type"), + msg_record_created = T("Office Type added"), + msg_record_modified = T("Office Type updated"), + msg_record_deleted = T("Office Type deleted"), + msg_list_empty = T("No Office Types currently registered")) represent = S3Represent(lookup=tablename, translate=True) office_type_id = S3ReusableField("office_type_id", "reference %s" % tablename, @@ -3584,20 +3698,19 @@ def model(self): *s3_meta_fields()) # CRUD strings - ADD_OFFICE = T("Create Office") crud_strings[tablename] = Storage( - label_create=T("Create Office"), - title_display=T("Office Details"), - title_list=T("Offices"), - title_update=T("Edit Office"), - title_upload=T("Import Offices"), - title_map=T("Map of Offices"), - label_list_button=T("List Offices"), - label_delete_button=T("Delete Office"), - msg_record_created=T("Office added"), - msg_record_modified=T("Office updated"), - msg_record_deleted=T("Office deleted"), - msg_list_empty=T("No Offices currently registered")) + label_create = T("Create Office"), + title_display = T("Office Details"), + title_list = T("Offices"), + title_update = T("Edit Office"), + title_upload = T("Import Offices"), + title_map = T("Map of Offices"), + label_list_button = T("List Offices"), + label_delete_button = T("Delete Office"), + msg_record_created = T("Office added"), + msg_record_modified = T("Office updated"), + msg_record_deleted = T("Office deleted"), + msg_list_empty = T("No Offices currently registered")) if settings.get_org_branches(): ORGANISATION = T("Organization/Branch") @@ -3633,26 +3746,23 @@ def model(self): filter_widgets = [ S3TextFilter(text_fields, - label=T("Search"), - #_class="filter-search", + label = T("Search"), + #_class = "filter-search", ), #S3OptionsFilter("office_type_id", - # label=T("Type"), - # widget="multiselect", - # #hidden=True, + # label = T("Type"), + # #hidden = True, # ), S3OptionsFilter("organisation_id", - label=ORGANISATION, - comment=comment, - represent="%(name)s", - widget="multiselect", - #hidden=True, + label = ORGANISATION, + comment = comment, + represent = "%(name)s", + #hidden = True, ), S3LocationFilter("location_id", - label=T("Location"), - levels=levels, - widget="multiselect", - #hidden=True, + label = T("Location"), + levels = levels, + #hidden = True, ), ] @@ -4050,8 +4160,6 @@ def org_root_organisation_name(organisation_id): if row: return row.name - return None - # ============================================================================= def org_organisation_requires(required = False, realms = None, @@ -4549,7 +4657,7 @@ def org_rheader(r, tabs=[]): skip_branches = False # If a filter is being applied to the Organisations, amend the tabs accordingly - type_filter = current.request.get_vars.get("organisation.organisation_type_id$name", + type_filter = current.request.get_vars.get("organisation_type.name", None) if type_filter: if type_filter == "Supplier": @@ -4760,24 +4868,21 @@ def prep(r): r.resource.add_filter(branch_filter) if not r.component or r.component_name == "branch": - type_filter = r.get_vars.get("organisation.organisation_type_id$name", None) + type_filter = r.get_vars.get("organisation_type.name", None) if type_filter: type_names = [name.lower().strip() for name in type_filter.split(",")] - field = r.table.organisation_type_id + field = s3db.org_organisation_organisation_type.organisation_type_id field.comment = None # Don't want to create new types here if len(type_names) == 1: # Strip Type from list_fields list_fields = s3db.get_config("org_organisation", "list_fields") try: - list_fields.remove("organisation_type_id") + list_fields.remove("organisation_organisation_type.organisation_type_id") except ValueError: # Already removed pass - else: - s3db.configure("org_organisation", - list_fields=list_fields) if not method or method == "create": # Default the Type type_table = s3db.org_organisation_type @@ -4788,6 +4893,11 @@ def prep(r): if type_id: field.default = type_id field.writable = False + crud_form = s3db.get_config("org_organisation", + "crud_form") + for e in crud_form.elements: + if e.selector == "organisation_type": + e.options.label = "" elif not method or method in ("create", "update"): # Limit the Type type_table = s3db.org_organisation_type @@ -4809,11 +4919,20 @@ def prep(r): # Branches default to the same type/country as the parent otable = r.table record = r.record - otable.organisation_type_id.default = record.organisation_type_id otable.region_id.default = record.region_id otable.country.default = record.country - # @ToDo: Update for components - #otable.sector_id.default = record.sector_id + ottable = s3db.org_organisation_organisation_type + row = db(ottable.organisation_id == record.id).select(ottable.organisation_type_id, + limitby=(0, 1), + ).first() + if row: + ottable.organisation_type_id.default = row.organisation_type_id + ostable = s3db.org_sector_organisation + row = db(ostable.organisation_id == record.id).select(ostable.sector_id, + limitby=(0, 1), + ).first() + if row: + ostable.sector_id.default = row.sector_id # Represent orgs without the parent prefix as we have that context already branch_represent = org_OrganisationRepresent(parent=False, skip_dt_orderby=True, @@ -4841,7 +4960,8 @@ def prep(r): atable.site_id.requires = field.requires # Stay within Organisation tab s3db.configure("asset_asset", - create_next = None) + create_next = None, + ) elif cname == "project" and r.link: # Hide/show host role after project selection in embed-widget @@ -4851,7 +4971,9 @@ def prep(r): s3.scripts.append("/%s/static/scripts/S3/s3.hide_host_role.js" % \ r.application) - s3db.configure("project_project", create_next=None) + s3db.configure("project_project", + create_next = None, + ) return True s3.prep = prep @@ -5415,11 +5537,8 @@ def org_update_affiliations(table, record): org_group_update_affiliations(record) elif rtype == "org_site" or rtype in current.auth.org_site_types: - org_site_update_affiliations(record) - return - # ============================================================================= def organisation_update_affiliations(record): """ @@ -5487,7 +5606,6 @@ def organisation_update_affiliations(record): for m in current_memberships: org, branch = m add_affiliation(org, branch, role=BRANCHES, role_type=OU) - return # ============================================================================= def org_group_update_affiliations(record): @@ -5556,7 +5674,6 @@ def org_group_update_affiliations(record): for m in current_memberships: group, org = m add_affiliation(group, org, role=MEMBERS, role_type=MEMBER) - return # ============================================================================= def org_site_update_affiliations(record): @@ -5606,7 +5723,6 @@ def org_site_update_affiliations(record): if o_pe_id and not seen: s3db.pr_add_affiliation(o_pe_id, s_pe_id, role=SITES, role_type=OU) - return # ============================================================================= def org_update_root_organisation(organisation_id, root_org=None): diff --git a/modules/s3db/project.py b/modules/s3db/project.py index a2539f6d50..fa3f198bec 100644 --- a/modules/s3db/project.py +++ b/modules/s3db/project.py @@ -3195,7 +3195,7 @@ def model(self): # CRUD Strings current.response.s3.crud_strings[tablename] = Storage( - label_create = T("New Sector"), + label_create = T("Add Sector"), title_display = T("Sector"), title_list = T("Sectors"), title_update = T("Edit Sector"), @@ -3382,7 +3382,7 @@ def model(self): *s3_meta_fields()) crud_strings[tablename] = Storage( - label_create = T("New Sector"), + label_create = T("Add Sector"), title_display = T("Sector"), title_list = T("Sectors"), title_update = T("Edit Sector"), diff --git a/modules/s3menus.py b/modules/s3menus.py index 18f1919329..f9723a5d21 100644 --- a/modules/s3menus.py +++ b/modules/s3menus.py @@ -1488,7 +1488,6 @@ def project(): ), M("Partner Organizations", f="partners")( M("Create", m="create"), - #M("Search"), M("Import", m="import", p="create"), ), M("Activity Types", f="activity_type", diff --git a/private/templates/ARC/config.py b/private/templates/ARC/config.py index a1388ca721..1bb1093163 100644 --- a/private/templates/ARC/config.py +++ b/private/templates/ARC/config.py @@ -157,12 +157,13 @@ def ifrc_realm_entity(table, row): use_user_organisation = False # Suppliers & Partners are owned by the user's organisation if realm_entity == 0 and tablename == "org_organisation": - ott = s3db.org_organisation_type - row = table[row.id] - row = db(table.organisation_type_id == ott.id).select(ott.name, - limitby=(0, 1) - ).first() - + ottable = s3db.org_organisation_type + ltable = db.org_organisation_organisation_type + query = (ltable.organisation_id == row.id) & \ + (ltable.organisation_type_id == ottable.id) + row = db(query).select(ottable.name, + limitby=(0, 1) + ).first() if row and row.name != "Red Cross / Red Crescent": use_user_organisation = True diff --git a/private/templates/CRMT/config.py b/private/templates/CRMT/config.py index 4ae4d6539d..9b9d92ace0 100644 --- a/private/templates/CRMT/config.py +++ b/private/templates/CRMT/config.py @@ -344,6 +344,10 @@ def filter_formstyle(row_id, label, widget, comment, hidden=False): # # Make Facility Types Hierarchical settings.org.facility_types_hierarchical = True +# Make Organisation Types Hierarchical +settings.org.organisation_types_hierarchical = True +# Make Organisation Types Multiple +settings.org.organisation_types_multiple = True # Enable the use of Organisation Groups settings.org.groups = "Coalition" # Set the label for Sites @@ -916,7 +920,7 @@ def custom_prep(r): table.name.label = T("Organization Name") if method in ("summary", "report"): - from s3.s3filter import S3OptionsFilter, S3TextFilter + from s3.s3filter import S3OptionsFilter, S3TextFilter, S3HierarchyFilter filter_widgets = [S3TextFilter(["name", "group_membership.group_id", "sector_organisation.sector_id", @@ -937,6 +941,10 @@ def custom_prep(r): label = T("Service"), header = True, ), + S3HierarchyFilter("organisation_organisation_type.organisation_type_id", + label = T("Type of Organization"), + #multiple = False, + ) ] s3.crud_strings.org_organisation.title_report = T("Organization Matrix") diff --git a/private/templates/CRMT/facility.csv b/private/templates/CRMT/facility.csv index 3783e42428..db832dbd62 100644 --- a/private/templates/CRMT/facility.csv +++ b/private/templates/CRMT/facility.csv @@ -1,107 +1,107 @@ -Name,Organisation,Type,Country,Building,Address,Postcode,L1,L2,L3,L4,Lat,Lon,Phone1,Phone2,Email,Fax,Comments -California Southern Baptist Convention,California Southern Baptist Convention Disaster Relief,Church,US,,678 East Shaw Ave,93710,California,Fresno County,Fresno,,36.808787,-119.774975,(559) 229-9533,,,, -Guadalupe Community Center,Catholic Charities of Los Angeles,Office,US,,21600 Hart St,91303,California,Los Angeles County,Los Angeles,Canoga Park,34.197381,-118.600415,(818) 340-2050,,,, -Oasis Community Center,Catholic Charities of Los Angeles,Office,US,,2045 San Gabriel Ave,90810,California,Los Angeles County,Carson,,33.792884,-118.223955,(562) 480-2166,,,, -San Juan Diego Center,Catholic Charities of Los Angeles,Office,US,,4171 North Taylor Ave,91731,California,Los Angeles County,El Monte,,34.07711867,-118.0364227,(626) 575-7652,,,, -Immigration and Refugee Services,Catholic Charities of Los Angeles,Office,US,,4322 San Fernando Road,91204,California,Los Angeles County,Glendale,,34.13146,-118.261418,(818) 502-2002,,,, -Glendale Community Center,Catholic Charities of Los Angeles,Office,US,,4322 San Fernando Road,91204,California,Los Angeles County,Glendale,,34.13146,-118.261418,(818) 409-3080,,,, -Refugee Resettlement Program,Catholic Charities of Los Angeles,Office,US,,4322 San Fernando Road,91204,California,Los Angeles County,Glendale,,34.13146,-118.261418,(818) 409-0057,,,, -Community Outreach Services,Catholic Charities of Los Angeles,Office,US,,16009 Cypress Ave,91706,California,Los Angeles County,Irwindale,,34.096092,-117.933627,(626) 338-5057,,,, -St. Margaret's Center,Catholic Charities of Los Angeles,Church,US,,10217 Inglewood Ave,90304,California,Los Angeles County,Lennox,,33.943534,-118.361357,(310) 672-2208,,,, -Elizabeth Ann Seton Residence,Catholic Charities of Los Angeles,Office,US,,123 East 14th St.,90813,California,Los Angeles County,Long Beach,,33.783935,-118.192004,(562) 233-5985,,,, -Gatekeeper Project,Catholic Charities of Los Angeles,Office,US,,123 East 14th St.,90813,California,Los Angeles County,Long Beach,,33.783935,-118.192004,(562) 480-2506 ,,,, -Long Beach Community Services Center,Catholic Charities of Los Angeles,Office,US,,123 East 14th St.,90813,California,Los Angeles County,Long Beach,,33.783935,-118.192004,(562) 591-1351,,,, -Project Achieve,Catholic Charities of Los Angeles,Office,US,,123 East 14th St.,90813,California,Los Angeles County,Long Beach,,33.783935,-118.192004,(562) 218-9864,,,, -"Adeste Child Care Program, Metro Area, Regional Administration",Catholic Charities of Los Angeles,Office,US,,601 E 23rd St,90011,California,Los Angeles County,Los Angeles,,34.024868,-118.261606,(213) 748-5346,,,, -Adeste Child Care Program San Gabriel Regional Administration,Catholic Charities of Los Angeles,Office,US,,1307 Warren St,90033,California,Los Angeles County,Los Angeles,,34.05235,-118.220466,(323) 264-4981,,,, -Angel's Flight MY CLUB Program,Catholic Charities of Los Angeles,Office,US,,8705 South Vermont Ave,90044,California,Los Angeles County,Los Angeles,,33.958834,-118.291917,(213) 413-2311,(800) 833-2499,,, -Art of Parenting,Catholic Charities of Los Angeles,Office,US,,1500 East Bridge St,90033,California,Los Angeles County,Los Angeles,,34.053346,-118.219928,(323) 263-4651,,,, -Brownson House,Catholic Charities of Los Angeles,Office,US,,1307 Warren St,90033,California,Los Angeles County,Los Angeles,,34.05235,-118.220466,(323) 264-8700,(323) 264-8701,,, -Catholic Youth Organization (CYO),Catholic Charities of Los Angeles,Office,US,,1530 James M. Wood Blvd,90015,California,Los Angeles County,Los Angeles,,34.050449,-118.272361,(213) 251-3454,,,, -Continuous Quality Improvement,Catholic Charities of Los Angeles,Office,US,,1530 James M. Wood Blvd,90015,California,Los Angeles County,Los Angeles,,34.050449,-118.272361,(213) 251-3459,,,, -Esperanza Immigrant Rights Project,Catholic Charities of Los Angeles,Office,US,,1530 James M. Wood Blvd,90015,California,Los Angeles County,Los Angeles,,34.050449,-118.272361,(213) 251-4505,,,, -Immigration Services,Catholic Charities of Los Angeles,Office,US,,1530 James M. Wood Blvd,90015,California,Los Angeles County,Los Angeles,,34.050449,-118.272361,(213) 251-3411,,,, -Refugee Resettlement Program,Catholic Charities of Los Angeles,Office,US,,1530 James M. Wood Blvd,90015,California,Los Angeles County,Los Angeles,,34.050449,-118.272361,(213) 251-3460,,,, -St Mary's Center,Catholic Charities of Los Angeles,Office,US,,4665 Willow Brook Ave,90029,California,Los Angeles County,Los Angeles,,34.089461,-118.293173,(323) 662-4391,,,, -Catholic Charities of Los Angeles,Catholic Charities of Los Angeles,Office,US,,1530 James M. Wood Blvd,90015,California,Los Angeles County,Los Angeles,,34.050449,-118.272361,(213) 251-3400,,,, -Adeste Child Care Program San Pedro Regional Administration,Catholic Charities of Los Angeles,Office,US,,5014 Passons Blvd,90660,California,Los Angeles County,Pico Rivera,,33.998218,-118.078131,(562) 480-2482,,,, -Pico Rivera Resource Center,Catholic Charities of Los Angeles,Office,US,,5014 Passons Blvd,90660,California,Los Angeles County,Pico Rivera,,33.998218,-118.078131,(562) 949-0937,,,, -Pomona Community Services,Catholic Charities of Los Angeles,Office,US,,248 E. Monterey Ave,91767,California,Los Angeles County,Pomona,,34.060607,-117.746992,(909) 629-0472,,,, -Counseling Services,Catholic Charities of Los Angeles,Office,US,,"461 W 6th St, Ste 202",90731,California,Los Angeles County,Los Angeles,San Pedro,33.738762,-118.287023,(310) 831-7111,,,, -Loaves & Fishes,Catholic Charities of Los Angeles,Office,US,,14640 Keswick St,91405,California,Los Angeles County,Los Angeles,Van Nuys,34.210266,-118.450963,(818) 997-0943,,,, -"Adeste Child Care Program, Western Area Regional Administration",Catholic Charities of Los Angeles,Office,US,,211 3rd Ave,90291,California,Los Angeles County,Los Angeles,Venice,33.998202,-118.477345,(310) 392-8701,,,, -Counseling Services,Catholic Charities of Los Angeles,Clinic,US,,211 3rd Ave,90291,California,Los Angeles County,Los Angeles,Venice,33.998202,-118.477345,(310) 399-1351,,,, -St. Robert's Center,Catholic Charities of Los Angeles,Office,US,,211 3rd Ave,90291,California,Los Angeles County,Los Angeles,Venice,33.998202,-118.477345,(310) 392-8701,,,, -Family Development Network,Catholic Charities of Los Angeles,Office,US,,1115 Mahar Ave,90744,California,Los Angeles County,Los Angeles,Wilmington,33.785597,-118.246457,(310) 834-7265,,,, -Mahar House Community Center,Catholic Charities of Los Angeles,Office,US,,1115 Mahar Ave,90744,California,Los Angeles County,Los Angeles,Wilmington,33.785597,-118.246457,(310) 834-7265,,,, -The Forum,Faithful Central Bible Church,Office,US,,3900 W Manchester Blvd,90305,California,Los Angeles County,Inglewood,,33.959952,-118.343314,(310) 330-7300,,,, -The Tabernacle,Faithful Central Bible Church,Office,US,,321 N Eucalyptus Ave,90301,California,Los Angeles County,Inglewood,,33.966166,-118.35941,,,,, -The Trinity Building,Faithful Central Bible Church,Office,US,,333 W Florence Ave,90301,California,Los Angeles County,Inglewood,,33.965533,-118.360769,(310) 330-8000,(800) 377-9782,,, -The Living Room,Faithful Central Bible Church,Office,US,,400 W Florence Ave,90301,California,Los Angeles County,Inglewood,,33.965597,-118.361871,,,,, -LA Regional Food Bank,LA Regional Food Bank,Food Bank,US,,1734 E 41st St,90057,California,Los Angeles County,Los Angeles,,34.00782776,-118.2420807,(323) 234-3030 ,,,, -Ascension Lutheran Church ,Lutheran Social Services of the Southwest,Office,US,,5820 West Blvd,90043,California,Los Angeles County,Los Angeles,,33.9883136,-118.335141,(323) 299-0729,,,, -Banking On Our Future,"Operation HOPE, Inc.",Office,US,,"707 Wilshire Blvd, 30th Fl",90017,California,Los Angeles County,Los Angeles,,34.049259,-118.257027,(213) 489-7511,(213) 891-2900,,, -HOPE Financial Literacy Empowerment Center,"Operation HOPE, Inc.",Office,US,,3721 S La Brea Ave,90016,California,Los Angeles County,Los Angeles,,34.01970751,-118.3556546,(323) 290-2405,(323) 290-2415,,, -Northwest Los Angeles Service Center,Tzu Chi Foundation,Office,US,,8963 Reseda Blvd,91324,California,Los Angeles County,Los Angeles,Northridge,34.2328539,-118.5361364,(818) 727-7689,,,, -Orange County Service Center,Tzu Chi Foundation,Office,US,,2851 Pullman St,92705,California,Orange County,Santa Ana,,33.70680618,-117.850174,(949) 833-0822,,,, -South Los Angeles Service Center,Tzu Chi Foundation,Office,US,,2315 Pacific Coast Hwy,90717,California,Los Angeles County,Lomita,,33.79002762,-118.3232269,(310) 326-2659,,,, -West Los Angeles Service Center,Tzu Chi Foundation,Office,US,,11701 Wilshire Blvd #7,90025,California,Los Angeles County,Los Angeles,,34.04941097,-118.4610231,(310) 473-5188,,,, -United Way Los Angeles,United Way - Los Angeles,Office,US,,"1150 S Olive St, Ste T500",90015,California,Los Angeles County,Los Angeles,,34.04008962,-118.2615446,(213) 808-6220,,,, -United Way Harbor Area,United Way - Los Angeles,Office,US,,3515 Linden Ave,90807,California,Los Angeles County,Long Beach,,33.82057953,-118.1869049,(562) 472-2140,,,, -Volunteer Center of Los Angeles,Volunteer Center of Los Angeles,Office,US,,8134 Van Nuys Blvd #200,91402,California,Los Angeles County,Los Angeles,Panorama City,34.21899414,-118.4482269,,,,, -Emergency Operations Center,Los Angeles City Emergency Management Department,Office,US,,500 E Temple St,90012,California,Los Angeles County,Los Angeles,,34.05046105,-118.2358423,,,,, -Los Angeles City Department of Animal Services,Los Angeles City Department of Animal Services,Office,US,,"221 N. Figueroa St, 5th fl",90012,California,Los Angeles County,Los Angeles,,34.05921555,-118.2510071,(888) 452-7381,,,, -Antelope Valley Public Health Center,Los Angeles County Department of Public Health,Clinic,US,,335-B East Ave K-6,93535,California,Los Angeles County,Lancaster,,34.76269913,-118.0916519,(661) 723-4526,,,, -Central Public Health Center,Los Angeles County Department of Public Health,Clinic,US,,241 N. Figueroa St,90012,California,Los Angeles County,Los Angeles,,34.05890599,-118.2505167,(213) 240-8204,,,, -Curtis-Tucker Public Health Center,Los Angeles County Department of Public Health,Clinic,US,,123 W Manchester Blvd,90301,California,Los Angeles County,Inglewood,,33.96243286,-118.3563919,(310) 419-5325,,,, -Glendale Public Health Center,Los Angeles County Department of Public Health,Clinic,US,,501 N Glendale Ave,91206,California,Los Angeles County,Glendale,,34.15312576,-118.2443237,(818) 500-5750,,,, -Hollywood/Wilshire Public Health Center,Los Angeles County Department of Public Health,Clinic,US,,5205 Melrose Ave,90038,California,Los Angeles County,Los Angeles,,34.08392715,-118.3141022,(323) 769-7800,,,, -"Martin Luther King, Jr. Center for Public Health",Los Angeles County Department of Public Health,Clinic,US,,11833 South Wilmington Ave,90059,California,Los Angeles County,Los Angeles,,33.925072,-118.239357,(323) 568-8100,,,, -Monrovia Public Health Center,Los Angeles County Department of Public Health,Clinic,US,,330 W Maple Ave,91016,California,Los Angeles County,Monrovia,,34.14141476,-118.0059797,(626) 256-1600,,,, -North Hollywood Public Health Center,Los Angeles County Department of Public Health,Clinic,US,,5300 Tujunga Ave,91601,California,Los Angeles County,Los Angeles,North Hollywood,34.16729736,-118.3783951,(818) 766-3982,,,, -Pacoima Public Health Center,Los Angeles County Department of Public Health,Clinic,US,,13300 Van Nuys Blvd,91331,California,Los Angeles County,Los Angeles,Pacoima,34.26496506,-118.4228287,(818) 896-1903,,,, -Pomona Public Health Center,Los Angeles County Department of Public Health,Clinic,US,,750 S Park Ave,91766,California,Los Angeles County,Pomona,,34.05273819,-117.7538605,(909) 868-0235,,,, -Ruth-Temple Public Health Center,Los Angeles County Department of Public Health,Clinic,US,,3834 S Western Ave,90062,California,Los Angeles County,Los Angeles,,34.01665878,-118.308548,(323) 730-3507,,,, -Simms/Mann Health and Wellness Center,Los Angeles County Department of Public Health,Clinic,US,,"2509 Pico Blvd, Rm 325",90405,California,Los Angeles County,Santa Monica,,34.02332687,-118.4633713,(310) 998-3203,,,, -Torrance Public Health Center,Los Angeles County Department of Public Health,Clinic,US,,710 Del Amo Blvd,90502,California,Los Angeles County,West Carson,,33.84633,-118.28606,(310) 354-2300,,,, -Whittier Public Health Center,Los Angeles County Department of Public Health,Clinic,US,,7643 S Painter Ave,90602,California,Los Angeles County,Whittier,,33.97212245,-118.032734,(562) 464-5350,,,, -Los Angeles County Department of Social Services,Los Angeles County Department of Social Services,Office,US,,12860 Crossroads Pkwy South,91746,California,Los Angeles County,Industry,,34.02873315,-118.0239384,(562) 908-8400,,,, -Los Angeles County Emergency Management Office,Los Angeles County Emergency Management Office,Office,US,,"500 W Temple St, Ste 493",90012,California,Los Angeles County,Los Angeles,,34.05654907,-118.2462997,(213) 974-1411,,,, -Incident Command Post,Los Angeles City Emergency Management Department,Office,US,,,,California,Los Angeles County,Los Angeles,,33.94813093,-118.3967473,,,,, -"Chapter Headquarters, West District Office",American Red Cross of Greater Los Angeles,Office,US,,11355 Ohio Avenue,90025,California,Los Angeles County,Los Angeles,,34.048073,-118.452446,(310) 445-9900,,,, -Central East District Office,American Red Cross of Greater Los Angeles,Office,US,,2227 S. Atlantic Blvd,90040,California,Los Angeles County,Los Angeles,,34.005764,-118.163742,(323) 780-7660,,,, -Koreatown/Wilshire District Office,American Red Cross of Greater Los Angeles,Office,US,,"501 Shatto Place, Suite 100",90020,California,Los Angeles County,Los Angeles,,34.065144,-118.289932,(213) 351-6765,,,, -Arcadia Chapter,American Red Cross of Greater Los Angeles,Office,US,,376 W Huntington Dr,91007,California,Los Angeles County,Arcadia,,34.131714,-118.044418,(626) 447-2193,,,, -East San Fernando Valley District Office,American Red Cross of Greater Los Angeles,Office,US,,731 N. Hollywood Way,91505,California,Los Angeles County,Burbank,,34.163639,-118.345268,(818) 842-5295,,,, -West San Fernando Valley District Office,American Red Cross of Greater Los Angeles,Office,US,,6800 Owensmouth Ave,91303,California,Los Angeles County,Los Angeles,Canoga Park,34.193779,-118.601501,(818) 593-3500,,,, -Claremont Chapter,American Red Cross of Greater Los Angeles,Office,US,,2065 N Indian Hill Blvd,91711,California,Los Angeles County,Claremont,,34.121128,-117.720657,(909) 624-0074,,,, -Glendale-Crescenta Valley,American Red Cross of Greater Los Angeles,Office,US,,1501 S. Brand Blvd,91204,California,Los Angeles County,Glendale,,34.127495,-118.255173,(818) 243-3121,,,, -South East District Office,American Red Cross of Greater Los Angeles,Office,US,,9800 S. La Cienega Blvd,90301,California,Los Angeles County,Inglewood,,33.9478,-118.370049,(310) 642-0230,,,, -Antelope Valley Chapter,American Red Cross of Greater Los Angeles,Office,US,,2715 E Ave P,93550,California,Los Angeles County,Palmdale,,34.602222,-118.077789,(661) 267-0650,,,, -San Gabriel Pomona Valley Chapter,American Red Cross of Greater Los Angeles,Office,US,,430 Madeline Dr,91105,California,Los Angeles County,Pasadena,,34.126476,-118.159615,(626) 799-0841,,,, -Santa Clarita Valley District Office,American Red Cross of Greater Los Angeles,Office,US,,"23838 Valencia Blvd, Suite 120",91355,California,Los Angeles County,Santa Clarita,,34.413586,-118.551575,(661) 259-1805,,,, -Santa Monica Chapter,American Red Cross of Greater Los Angeles,Office,US,,1450 11th St,90401,California,Los Angeles County,Santa Monica,,34.0205,-118.48755,(310) 394-3773,,,, -South Bay District Office,American Red Cross of Greater Los Angeles,Office,US,,"1995 W. 190th Street, Suite 100",90504,Californi,Los Angeles County,Torrance,,33.8596,-118.313,(310) 225-2900,,,, -St. Mary's Center,Catholic Charities of Los Angeles,Office,US,,4665 Willow Brook Ave,90029,California,Los Angeles County,Los Angeles,,34.089461,-118.293173,(323) 662-4391,,,, -Angel's Flight Runaway & Homeless Youth Services,Catholic Charities of Los Angeles,Clinic,US,,357 S Westlake Ave,90057,California,Los Angeles County,Los Angeles,,34.061518,-118.272079,(213) 413-2311,(800) 833-2499,,, -Good Shepherd Center for Homeless Women and Children,Catholic Charities of Los Angeles,Clinic,US,,1671 Beverly Blvd,90026,California,Los Angeles County,Los Angeles,,34.064319,-118.265074,(213) 235-1460,,,, -El Santo Nino Community Center,Catholic Charities of Los Angeles,Office,US,,601 E 23rd St,90011,California,Los Angeles County,Los Angeles,,34.024868,-118.261606,(213) 748-5246,,,, -Temporary Skilled Worker Center,Catholic Charities of Los Angeles,Office,US,,1190 S Flower St,91502,California,Los Angeles County,Burbank,,34.170277,-118.301488,(818) 566-7148,,,, -Capinteria Community Services,Catholic Charities of Los Angeles,Office,US,,941 Walnut St,93013,California,Santa Barbara County,Carpinteria,,34.396921,-119.517031,(805) 684-8621,,,, -Lompoc Community Services,Catholic Charities of Los Angeles,Office,US,,903 East Chestnut Ave,93436,California,Santa Barbara County,Lompoc,,34.642148,-120.447498,(805) 736-4886,,,, -Lompoc Food Pantry,Catholic Charities of Los Angeles,Office,US,,903 East Chestnut Ave,93436,California,Santa Barbara County,Lompoc,,34.642148,-120.447498,(805) 736-4886,,,, -Counseling Services,Catholic Charities of Los Angeles,Clinic,US,,609 East Haley St,93103,California,Santa Barbara County,Santa Barbara,,34.423369,-119.688546,(805) 965-7045,,,, -Santa Barbara Community Services,Catholic Charities of Los Angeles,Office,US,,609 East Haley St,93103,California,Santa Barbara County,Santa Barbara,,34.423369,-119.688546,(805) 965-7045,,,, -Thrifty Shopper at Catholic Charities (Thrift Store),Catholic Charities of Los Angeles,Office,US,,609 East Haley St,93103,California,Santa Barbara County,Santa Barbara,,34.423369,-119.688546,(805) 966-9659,,,, -Cuyama Valley Community Services,Catholic Charities of Los Angeles,Office,US,,607 West Main St,93454,California,Santa Barbara County,Santa Maria,,34.953208,-120.442719,(805) 922-2059,,,, -Guadalupe Community Services,Catholic Charities of Los Angeles,Office,US,,607 West Main St,93454,California,Santa Barbara County,Santa Maria,,34.953208,-120.442719,(805) 922-2059,,,, -Santa Maria Community Services,Catholic Charities of Los Angeles,Office,US,,607 West Main St,93454,California,Santa Barbara County,Santa Maria,,34.953208,-120.442719,(805) 922-2059,,,, -Thrifty Shopper at Catholic Charities (Thrift Store),Catholic Charities of Los Angeles,Office,US,,605 West Main St,93454,California,Santa Barbara County,Santa Maria,,34.953208,-120.442678,(805) 922-4174,,,, -Older Adult Services and Intervention System (OASIS) Camarillo,Catholic Charities of Los Angeles,Office,US,,2532 Ventura Blvd,93010,California,Ventura County,Camarillo,,34.216168,-119.035777,(805) 987-2083,,,, -"Older Adult Services and Intervention System, Fillmore/Piru",Catholic Charities of Los Angeles,Office,US,,1048 West Ventura St,93016,California,Ventura County,Fillmore,,34.08226,-118.031696,(805) 794-5929,,,, -Moorpark Community Services,Catholic Charities of Los Angeles,Office,US,,609 Fitch Ave,93021,California,Ventura County,Moorpark,,34.284058,-118.873006,(805) 529-0720,,,, -Older Adult Services and Intervention System (OASIS) Moorpark,Catholic Charities of Los Angeles,Office,US,,609 Fitch Ave,93021,California,Ventura County,Moorpark,,34.284058,-118.873006,(805) 794-5929,,,, -Oxnard Community Services,Catholic Charities of Los Angeles,Office,US,,502 North A St,93030,California,Ventura County,Oxnard,,34.207017,-119.178491,(805) 485-2900,,,, -Older Adult Services and Intervention System (OASIS) Santa Paula,Catholic Charities of Los Angeles,Office,US,,427 North Oak St,93061,California,Ventura County,Santa Paula,,34.360545,-119.059482,(805) 794-5929,,,, -Adeste Child Care Program Ventura County Regional Administration,Catholic Charities of Los Angeles,Office,US,,"303 North Ventura Ave, Ste B",93001,California,Ventura County,Ventura,,34.28471,-119.299823,(805) 643-4760,,,, -Ventura Community Services Center,Catholic Charities of Los Angeles,Office,US,,"303 North Ventura Ave, Ste C",93001,California,Ventura County,Ventura,,34.28471,-119.299823,(805) 643-4693,,,, \ No newline at end of file +Name,Organisation,Type,Country,Address,Postcode,L1,L2,L3,L4,Lat,Lon,Phone1,Phone2 +California Southern Baptist Convention,California Southern Baptist Convention Disaster Relief,Church,US,678 East Shaw Ave,93710,California,Fresno County,Fresno,,36.808787,-119.774975,(559) 229-9533, +Guadalupe Community Center,Catholic Charities of Los Angeles,Office,US,21600 Hart St,91303,California,Los Angeles County,Los Angeles,Canoga Park,34.197381,-118.600415,(818) 340-2050, +Oasis Community Center,Catholic Charities of Los Angeles,Office,US,2045 San Gabriel Ave,90810,California,Los Angeles County,Carson,,33.792884,-118.223955,(562) 480-2166, +San Juan Diego Center,Catholic Charities of Los Angeles,Office,US,4171 North Taylor Ave,91731,California,Los Angeles County,El Monte,,34.07711867,-118.0364227,(626) 575-7652, +Immigration and Refugee Services,Catholic Charities of Los Angeles,Office,US,4322 San Fernando Road,91204,California,Los Angeles County,Glendale,,34.13146,-118.261418,(818) 502-2002, +Glendale Community Center,Catholic Charities of Los Angeles,Office,US,4322 San Fernando Road,91204,California,Los Angeles County,Glendale,,34.13146,-118.261418,(818) 409-3080, +Refugee Resettlement Program,Catholic Charities of Los Angeles,Office,US,4322 San Fernando Road,91204,California,Los Angeles County,Glendale,,34.13146,-118.261418,(818) 409-0057, +Community Outreach Services,Catholic Charities of Los Angeles,Office,US,16009 Cypress Ave,91706,California,Los Angeles County,Irwindale,,34.096092,-117.933627,(626) 338-5057, +St. Margaret's Center,Catholic Charities of Los Angeles,Church,US,10217 Inglewood Ave,90304,California,Los Angeles County,Lennox,,33.943534,-118.361357,(310) 672-2208, +Elizabeth Ann Seton Residence,Catholic Charities of Los Angeles,Office,US,123 East 14th St.,90813,California,Los Angeles County,Long Beach,,33.783935,-118.192004,(562) 233-5985, +Gatekeeper Project,Catholic Charities of Los Angeles,Office,US,123 East 14th St.,90813,California,Los Angeles County,Long Beach,,33.783935,-118.192004,(562) 480-2506 , +Long Beach Community Services Center,Catholic Charities of Los Angeles,Office,US,123 East 14th St.,90813,California,Los Angeles County,Long Beach,,33.783935,-118.192004,(562) 591-1351, +Project Achieve,Catholic Charities of Los Angeles,Office,US,123 East 14th St.,90813,California,Los Angeles County,Long Beach,,33.783935,-118.192004,(562) 218-9864, +"Adeste Child Care Program, Metro Area, Regional Administration",Catholic Charities of Los Angeles,Office,US,601 E 23rd St,90011,California,Los Angeles County,Los Angeles,,34.024868,-118.261606,(213) 748-5346, +Adeste Child Care Program San Gabriel Regional Administration,Catholic Charities of Los Angeles,Office,US,1307 Warren St,90033,California,Los Angeles County,Los Angeles,,34.05235,-118.220466,(323) 264-4981, +Angel's Flight MY CLUB Program,Catholic Charities of Los Angeles,Office,US,8705 South Vermont Ave,90044,California,Los Angeles County,Los Angeles,,33.958834,-118.291917,(213) 413-2311,(800) 833-2499 +Art of Parenting,Catholic Charities of Los Angeles,Office,US,1500 East Bridge St,90033,California,Los Angeles County,Los Angeles,,34.053346,-118.219928,(323) 263-4651, +Brownson House,Catholic Charities of Los Angeles,Office,US,1307 Warren St,90033,California,Los Angeles County,Los Angeles,,34.05235,-118.220466,(323) 264-8700,(323) 264-8701 +Catholic Youth Organization (CYO),Catholic Charities of Los Angeles,Office,US,1530 James M. Wood Blvd,90015,California,Los Angeles County,Los Angeles,,34.050449,-118.272361,(213) 251-3454, +Continuous Quality Improvement,Catholic Charities of Los Angeles,Office,US,1530 James M. Wood Blvd,90015,California,Los Angeles County,Los Angeles,,34.050449,-118.272361,(213) 251-3459, +Esperanza Immigrant Rights Project,Catholic Charities of Los Angeles,Office,US,1530 James M. Wood Blvd,90015,California,Los Angeles County,Los Angeles,,34.050449,-118.272361,(213) 251-4505, +Immigration Services,Catholic Charities of Los Angeles,Office,US,1530 James M. Wood Blvd,90015,California,Los Angeles County,Los Angeles,,34.050449,-118.272361,(213) 251-3411, +Refugee Resettlement Program,Catholic Charities of Los Angeles,Office,US,1530 James M. Wood Blvd,90015,California,Los Angeles County,Los Angeles,,34.050449,-118.272361,(213) 251-3460, +St Mary's Center,Catholic Charities of Los Angeles,Office,US,4665 Willow Brook Ave,90029,California,Los Angeles County,Los Angeles,,34.089461,-118.293173,(323) 662-4391, +Catholic Charities of Los Angeles,Catholic Charities of Los Angeles,Office,US,1530 James M. Wood Blvd,90015,California,Los Angeles County,Los Angeles,,34.050449,-118.272361,(213) 251-3400, +Adeste Child Care Program San Pedro Regional Administration,Catholic Charities of Los Angeles,Office,US,5014 Passons Blvd,90660,California,Los Angeles County,Pico Rivera,,33.998218,-118.078131,(562) 480-2482, +Pico Rivera Resource Center,Catholic Charities of Los Angeles,Office,US,5014 Passons Blvd,90660,California,Los Angeles County,Pico Rivera,,33.998218,-118.078131,(562) 949-0937, +Pomona Community Services,Catholic Charities of Los Angeles,Office,US,248 E. Monterey Ave,91767,California,Los Angeles County,Pomona,,34.060607,-117.746992,(909) 629-0472, +Counseling Services,Catholic Charities of Los Angeles,Office,US,"461 W 6th St, Ste 202",90731,California,Los Angeles County,Los Angeles,San Pedro,33.738762,-118.287023,(310) 831-7111, +Loaves & Fishes,Catholic Charities of Los Angeles,Office,US,14640 Keswick St,91405,California,Los Angeles County,Los Angeles,Van Nuys,34.210266,-118.450963,(818) 997-0943, +"Adeste Child Care Program, Western Area Regional Administration",Catholic Charities of Los Angeles,Office,US,211 3rd Ave,90291,California,Los Angeles County,Los Angeles,Venice,33.998202,-118.477345,(310) 392-8701, +Counseling Services,Catholic Charities of Los Angeles,Clinic,US,211 3rd Ave,90291,California,Los Angeles County,Los Angeles,Venice,33.998202,-118.477345,(310) 399-1351, +St. Robert's Center,Catholic Charities of Los Angeles,Office,US,211 3rd Ave,90291,California,Los Angeles County,Los Angeles,Venice,33.998202,-118.477345,(310) 392-8701, +Family Development Network,Catholic Charities of Los Angeles,Office,US,1115 Mahar Ave,90744,California,Los Angeles County,Los Angeles,Wilmington,33.785597,-118.246457,(310) 834-7265, +Mahar House Community Center,Catholic Charities of Los Angeles,Office,US,1115 Mahar Ave,90744,California,Los Angeles County,Los Angeles,Wilmington,33.785597,-118.246457,(310) 834-7265, +The Forum,Faithful Central Bible Church,Office,US,3900 W Manchester Blvd,90305,California,Los Angeles County,Inglewood,,33.959952,-118.343314,(310) 330-7300, +The Tabernacle,Faithful Central Bible Church,Office,US,321 N Eucalyptus Ave,90301,California,Los Angeles County,Inglewood,,33.966166,-118.35941,, +The Trinity Building,Faithful Central Bible Church,Office,US,333 W Florence Ave,90301,California,Los Angeles County,Inglewood,,33.965533,-118.360769,(310) 330-8000,(800) 377-9782 +The Living Room,Faithful Central Bible Church,Office,US,400 W Florence Ave,90301,California,Los Angeles County,Inglewood,,33.965597,-118.361871,, +LA Regional Food Bank,LA Regional Food Bank,Food Bank,US,1734 E 41st St,90057,California,Los Angeles County,Los Angeles,,34.00782776,-118.2420807,(323) 234-3030 , +Ascension Lutheran Church ,Lutheran Social Services of the Southwest,Office,US,5820 West Blvd,90043,California,Los Angeles County,Los Angeles,,33.9883136,-118.335141,(323) 299-0729, +Banking On Our Future,"Operation HOPE, Inc.",Office,US,"707 Wilshire Blvd, 30th Fl",90017,California,Los Angeles County,Los Angeles,,34.049259,-118.257027,(213) 489-7511,(213) 891-2900 +HOPE Financial Literacy Empowerment Center,"Operation HOPE, Inc.",Office,US,3721 S La Brea Ave,90016,California,Los Angeles County,Los Angeles,,34.01970751,-118.3556546,(323) 290-2405,(323) 290-2415 +Northwest Los Angeles Service Center,Tzu Chi Foundation,Office,US,8963 Reseda Blvd,91324,California,Los Angeles County,Los Angeles,Northridge,34.2328539,-118.5361364,(818) 727-7689, +Orange County Service Center,Tzu Chi Foundation,Office,US,2851 Pullman St,92705,California,Orange County,Santa Ana,,33.70680618,-117.850174,(949) 833-0822, +South Los Angeles Service Center,Tzu Chi Foundation,Office,US,2315 Pacific Coast Hwy,90717,California,Los Angeles County,Lomita,,33.79002762,-118.3232269,(310) 326-2659, +West Los Angeles Service Center,Tzu Chi Foundation,Office,US,11701 Wilshire Blvd #7,90025,California,Los Angeles County,Los Angeles,,34.04941097,-118.4610231,(310) 473-5188, +United Way Los Angeles,United Way - Los Angeles,Office,US,"1150 S Olive St, Ste T500",90015,California,Los Angeles County,Los Angeles,,34.04008962,-118.2615446,(213) 808-6220, +United Way Harbor Area,United Way - Los Angeles,Office,US,3515 Linden Ave,90807,California,Los Angeles County,Long Beach,,33.82057953,-118.1869049,(562) 472-2140, +Volunteer Center of Los Angeles,Volunteer Center of Los Angeles,Office,US,8134 Van Nuys Blvd #200,91402,California,Los Angeles County,Los Angeles,Panorama City,34.21899414,-118.4482269,, +Emergency Operations Center,Los Angeles City Emergency Management Department,Office,US,500 E Temple St,90012,California,Los Angeles County,Los Angeles,,34.05046105,-118.2358423,, +Los Angeles City Department of Animal Services,Los Angeles City Department of Animal Services,Office,US,"221 N. Figueroa St, 5th fl",90012,California,Los Angeles County,Los Angeles,,34.05921555,-118.2510071,(888) 452-7381, +Antelope Valley Public Health Center,Los Angeles County Department of Public Health,Clinic,US,335-B East Ave K-6,93535,California,Los Angeles County,Lancaster,,34.76269913,-118.0916519,(661) 723-4526, +Central Public Health Center,Los Angeles County Department of Public Health,Clinic,US,241 N. Figueroa St,90012,California,Los Angeles County,Los Angeles,,34.05890599,-118.2505167,(213) 240-8204, +Curtis-Tucker Public Health Center,Los Angeles County Department of Public Health,Clinic,US,123 W Manchester Blvd,90301,California,Los Angeles County,Inglewood,,33.96243286,-118.3563919,(310) 419-5325, +Glendale Public Health Center,Los Angeles County Department of Public Health,Clinic,US,501 N Glendale Ave,91206,California,Los Angeles County,Glendale,,34.15312576,-118.2443237,(818) 500-5750, +Hollywood/Wilshire Public Health Center,Los Angeles County Department of Public Health,Clinic,US,5205 Melrose Ave,90038,California,Los Angeles County,Los Angeles,,34.08392715,-118.3141022,(323) 769-7800, +"Martin Luther King, Jr. Center for Public Health",Los Angeles County Department of Public Health,Clinic,US,11833 South Wilmington Ave,90059,California,Los Angeles County,Los Angeles,,33.925072,-118.239357,(323) 568-8100, +Monrovia Public Health Center,Los Angeles County Department of Public Health,Clinic,US,330 W Maple Ave,91016,California,Los Angeles County,Monrovia,,34.14141476,-118.0059797,(626) 256-1600, +North Hollywood Public Health Center,Los Angeles County Department of Public Health,Clinic,US,5300 Tujunga Ave,91601,California,Los Angeles County,Los Angeles,North Hollywood,34.16729736,-118.3783951,(818) 766-3982, +Pacoima Public Health Center,Los Angeles County Department of Public Health,Clinic,US,13300 Van Nuys Blvd,91331,California,Los Angeles County,Los Angeles,Pacoima,34.26496506,-118.4228287,(818) 896-1903, +Pomona Public Health Center,Los Angeles County Department of Public Health,Clinic,US,750 S Park Ave,91766,California,Los Angeles County,Pomona,,34.05273819,-117.7538605,(909) 868-0235, +Ruth-Temple Public Health Center,Los Angeles County Department of Public Health,Clinic,US,3834 S Western Ave,90062,California,Los Angeles County,Los Angeles,,34.01665878,-118.308548,(323) 730-3507, +Simms/Mann Health and Wellness Center,Los Angeles County Department of Public Health,Clinic,US,"2509 Pico Blvd, Rm 325",90405,California,Los Angeles County,Santa Monica,,34.02332687,-118.4633713,(310) 998-3203, +Torrance Public Health Center,Los Angeles County Department of Public Health,Clinic,US,710 Del Amo Blvd,90502,California,Los Angeles County,West Carson,,33.84633,-118.28606,(310) 354-2300, +Whittier Public Health Center,Los Angeles County Department of Public Health,Clinic,US,7643 S Painter Ave,90602,California,Los Angeles County,Whittier,,33.97212245,-118.032734,(562) 464-5350, +Los Angeles County Department of Social Services,Los Angeles County Department of Social Services,Office,US,12860 Crossroads Pkwy South,91746,California,Los Angeles County,Industry,,34.02873315,-118.0239384,(562) 908-8400, +Los Angeles County Emergency Management Office,Los Angeles County Emergency Management Office,Office,US,"500 W Temple St, Ste 493",90012,California,Los Angeles County,Los Angeles,,34.05654907,-118.2462997,(213) 974-1411, +Incident Command Post,Los Angeles City Emergency Management Department,Office,US,,,California,Los Angeles County,Los Angeles,,33.94813093,-118.3967473,, +"Chapter Headquarters, West District Office",American Red Cross of Greater Los Angeles,Office,US,11355 Ohio Avenue,90025,California,Los Angeles County,Los Angeles,,34.048073,-118.452446,(310) 445-9900, +Central East District Office,American Red Cross of Greater Los Angeles,Office,US,2227 S. Atlantic Blvd,90040,California,Los Angeles County,Los Angeles,,34.005764,-118.163742,(323) 780-7660, +Koreatown/Wilshire District Office,American Red Cross of Greater Los Angeles,Office,US,"501 Shatto Place, Suite 100",90020,California,Los Angeles County,Los Angeles,,34.065144,-118.289932,(213) 351-6765, +Arcadia Chapter,American Red Cross of Greater Los Angeles,Office,US,376 W Huntington Dr,91007,California,Los Angeles County,Arcadia,,34.131714,-118.044418,(626) 447-2193, +East San Fernando Valley District Office,American Red Cross of Greater Los Angeles,Office,US,731 N. Hollywood Way,91505,California,Los Angeles County,Burbank,,34.163639,-118.345268,(818) 842-5295, +West San Fernando Valley District Office,American Red Cross of Greater Los Angeles,Office,US,6800 Owensmouth Ave,91303,California,Los Angeles County,Los Angeles,Canoga Park,34.193779,-118.601501,(818) 593-3500, +Claremont Chapter,American Red Cross of Greater Los Angeles,Office,US,2065 N Indian Hill Blvd,91711,California,Los Angeles County,Claremont,,34.121128,-117.720657,(909) 624-0074, +Glendale-Crescenta Valley,American Red Cross of Greater Los Angeles,Office,US,1501 S. Brand Blvd,91204,California,Los Angeles County,Glendale,,34.127495,-118.255173,(818) 243-3121, +South East District Office,American Red Cross of Greater Los Angeles,Office,US,9800 S. La Cienega Blvd,90301,California,Los Angeles County,Inglewood,,33.9478,-118.370049,(310) 642-0230, +Antelope Valley Chapter,American Red Cross of Greater Los Angeles,Office,US,2715 E Ave P,93550,California,Los Angeles County,Palmdale,,34.602222,-118.077789,(661) 267-0650, +San Gabriel Pomona Valley Chapter,American Red Cross of Greater Los Angeles,Office,US,430 Madeline Dr,91105,California,Los Angeles County,Pasadena,,34.126476,-118.159615,(626) 799-0841, +Santa Clarita Valley District Office,American Red Cross of Greater Los Angeles,Office,US,"23838 Valencia Blvd, Suite 120",91355,California,Los Angeles County,Santa Clarita,,34.413586,-118.551575,(661) 259-1805, +Santa Monica Chapter,American Red Cross of Greater Los Angeles,Office,US,1450 11th St,90401,California,Los Angeles County,Santa Monica,,34.0205,-118.48755,(310) 394-3773, +South Bay District Office,American Red Cross of Greater Los Angeles,Office,US,"1995 W. 190th Street, Suite 100",90504,Californi,Los Angeles County,Torrance,,33.8596,-118.313,(310) 225-2900, +St. Mary's Center,Catholic Charities of Los Angeles,Office,US,4665 Willow Brook Ave,90029,California,Los Angeles County,Los Angeles,,34.089461,-118.293173,(323) 662-4391, +Angel's Flight Runaway & Homeless Youth Services,Catholic Charities of Los Angeles,Clinic,US,357 S Westlake Ave,90057,California,Los Angeles County,Los Angeles,,34.061518,-118.272079,(213) 413-2311,(800) 833-2499 +Good Shepherd Center for Homeless Women and Children,Catholic Charities of Los Angeles,Clinic,US,1671 Beverly Blvd,90026,California,Los Angeles County,Los Angeles,,34.064319,-118.265074,(213) 235-1460, +El Santo Nino Community Center,Catholic Charities of Los Angeles,Office,US,601 E 23rd St,90011,California,Los Angeles County,Los Angeles,,34.024868,-118.261606,(213) 748-5246, +Temporary Skilled Worker Center,Catholic Charities of Los Angeles,Office,US,1190 S Flower St,91502,California,Los Angeles County,Burbank,,34.170277,-118.301488,(818) 566-7148, +Capinteria Community Services,Catholic Charities of Los Angeles,Office,US,941 Walnut St,93013,California,Santa Barbara County,Carpinteria,,34.396921,-119.517031,(805) 684-8621, +Lompoc Community Services,Catholic Charities of Los Angeles,Office,US,903 East Chestnut Ave,93436,California,Santa Barbara County,Lompoc,,34.642148,-120.447498,(805) 736-4886, +Lompoc Food Pantry,Catholic Charities of Los Angeles,Office,US,903 East Chestnut Ave,93436,California,Santa Barbara County,Lompoc,,34.642148,-120.447498,(805) 736-4886, +Counseling Services,Catholic Charities of Los Angeles,Clinic,US,609 East Haley St,93103,California,Santa Barbara County,Santa Barbara,,34.423369,-119.688546,(805) 965-7045, +Santa Barbara Community Services,Catholic Charities of Los Angeles,Office,US,609 East Haley St,93103,California,Santa Barbara County,Santa Barbara,,34.423369,-119.688546,(805) 965-7045, +Thrifty Shopper at Catholic Charities (Thrift Store),Catholic Charities of Los Angeles,Office,US,609 East Haley St,93103,California,Santa Barbara County,Santa Barbara,,34.423369,-119.688546,(805) 966-9659, +Cuyama Valley Community Services,Catholic Charities of Los Angeles,Office,US,607 West Main St,93454,California,Santa Barbara County,Santa Maria,,34.953208,-120.442719,(805) 922-2059, +Guadalupe Community Services,Catholic Charities of Los Angeles,Office,US,607 West Main St,93454,California,Santa Barbara County,Santa Maria,,34.953208,-120.442719,(805) 922-2059, +Santa Maria Community Services,Catholic Charities of Los Angeles,Office,US,607 West Main St,93454,California,Santa Barbara County,Santa Maria,,34.953208,-120.442719,(805) 922-2059, +Thrifty Shopper at Catholic Charities (Thrift Store),Catholic Charities of Los Angeles,Office,US,605 West Main St,93454,California,Santa Barbara County,Santa Maria,,34.953208,-120.442678,(805) 922-4174, +Older Adult Services and Intervention System (OASIS) Camarillo,Catholic Charities of Los Angeles,Office,US,2532 Ventura Blvd,93010,California,Ventura County,Camarillo,,34.216168,-119.035777,(805) 987-2083, +"Older Adult Services and Intervention System, Fillmore/Piru",Catholic Charities of Los Angeles,Office,US,1048 West Ventura St,93016,California,Ventura County,Fillmore,,34.08226,-118.031696,(805) 794-5929, +Moorpark Community Services,Catholic Charities of Los Angeles,Office,US,609 Fitch Ave,93021,California,Ventura County,Moorpark,,34.284058,-118.873006,(805) 529-0720, +Older Adult Services and Intervention System (OASIS) Moorpark,Catholic Charities of Los Angeles,Office,US,609 Fitch Ave,93021,California,Ventura County,Moorpark,,34.284058,-118.873006,(805) 794-5929, +Oxnard Community Services,Catholic Charities of Los Angeles,Office,US,502 North A St,93030,California,Ventura County,Oxnard,,34.207017,-119.178491,(805) 485-2900, +Older Adult Services and Intervention System (OASIS) Santa Paula,Catholic Charities of Los Angeles,Office,US,427 North Oak St,93061,California,Ventura County,Santa Paula,,34.360545,-119.059482,(805) 794-5929, +Adeste Child Care Program Ventura County Regional Administration,Catholic Charities of Los Angeles,Office,US,"303 North Ventura Ave, Ste B",93001,California,Ventura County,Ventura,,34.28471,-119.299823,(805) 643-4760, +Ventura Community Services Center,Catholic Charities of Los Angeles,Office,US,"303 North Ventura Ave, Ste C",93001,California,Ventura County,Ventura,,34.28471,-119.299823,(805) 643-4693, diff --git a/private/templates/CRMT/organisation.csv b/private/templates/CRMT/organisation.csv index be34d278b3..4d932ddda7 100644 --- a/private/templates/CRMT/organisation.csv +++ b/private/templates/CRMT/organisation.csv @@ -1,22 +1,24 @@ -Organisation,Branch,Acronym,Sectors,Services,Type,Country,Website,Twitter,Donation Phone,Comments -Los Angeles City Emergency Management Department,,EMD,"Government, Emergency Management",Disaster information/risk communication,Government,US,http://emergency.lacity.org,ReadyLA,, -CERT Los Angeles,,CERT,"Community, Emergency Management",Disaster information/risk communication,National NGO,US,http://www.cert-la.com,,, -American Red Cross of Greater Los Angeles,,ARC,"Community, Housing / Shelter","Disaster information/risk communication, Notification / mobilization of staff, Volunteer operations, Shelter",Red Cross / Red Crescent,US,http://redcrossla.org,redcrossla,, -LA Works,,,Community,Volunteer operations ,National NGO,US,http://www.laworks.com,,, -Volunteer Center of Los Angeles,,VCLA,Community,Volunteer operations ,National NGO,US,http://www.vcla.net,,, -Disaster Healthcare Volunteers,,DHV,Community,Disaster information/risk communication,National NGO,US,http://www.lacountydhv.org,,, -Salvation Army,,,Cultural / Faith Based Organization,Volunteer operations ,National NGO,US,http://www1.usw.salvationarmy.org/USW/www_usw_southcal.nsf/,,, -Catholic Charities of Los Angeles,,,Cultural / Faith Based Organization,Volunteer operations ,National NGO,US,http://www.catholiccharitiesla.org,,, -California Southern Baptist Convention Disaster Relief,,,Cultural / Faith Based Organization,Volunteer operations ,National NGO,US,http://www.csbc.com/disasterrelief,,, -Faithful Central Bible Church,,,Cultural / Faith Based Organization,Volunteer operations ,National NGO,US,http://www.faithfulcentral.com,,, -LA Regional Food Bank,,,Community,Food safety and security,National NGO,US,http://www.lafoodbank.org,,, -Lutheran Social Services of the Southwest,,,Cultural / Faith Based Organization,,National NGO,US,http://www.lss-sw.org,,, -"Operation HOPE, Inc.",,,Community,Organizational or community preparedness,National NGO,US,http://www.operationhope.org,,, -Tzu Chi Foundation,,,Cultural / Faith Based Organization,Volunteer operations ,National NGO,US,http://www.us.tzuchi.org/us/en/,,, -United Way - Los Angeles,,,Community,Organizational or community preparedness,National NGO,US,http://www.unitedwayla.org,,, -Los Angeles City Department of Animal Services,,,Government,Animal services,Government,US,http://www.laanimalservices.com,,, -Los Angeles County Chief Information Office,,,Government,,Government,US,http://egis3.lacounty.gov/egis/,,, -Los Angeles County Department of Public Health,,,Government,"Disaster information/risk communication, Notification / mobilization of staff, Pharmacies, Surveillance",Government,US,http://publichealth.lacounty.gov,,, -Los Angeles County Department of Social Services,,,Government,Crisis counseling,Government,US,http://www.ladpss.org,,, -Los Angeles County Emergency Management Office,,,"Government, Emergency Management",Disaster information/risk communication,Government,US,http://www.lacoa.org,,, -Walmart,,,Business,Pharmacies,Business,US,http://www.walmart.com,,, \ No newline at end of file +Organisation,Acronym,Sectors,Services,Type,SubType,SubSubType,Country,Website,Twitter,Donation Phone,Comments +Los Angeles City Emergency Management Department,EMD,"Government, Emergency Management",Disaster information/risk communication,,,,US,http://emergency.lacity.org,ReadyLA,, +CERT Los Angeles,CERT,"Community, Emergency Management",Disaster information/risk communication,,,,US,http://www.cert-la.com,,, +American Red Cross of Greater Los Angeles,ARC,"Community, Housing / Shelter","Disaster information/risk communication, Notification / mobilization of staff, Volunteer operations, Shelter",,,,US,http://redcrossla.org,redcrossla,, +LA Works,,Community,Volunteer operations,,,,US,http://www.laworks.com,,, +Volunteer Center of Los Angeles,VCLA,Community,Volunteer operations,,,,US,http://www.vcla.net,,, +Disaster Healthcare Volunteers,DHV,Community,Disaster information/risk communication,,,,US,http://www.lacountydhv.org,,, +Salvation Army,,Cultural / Faith Based Organization,Volunteer operations,,,,US,http://www1.usw.salvationarmy.org/USW/www_usw_southcal.nsf/,,, +Catholic Charities of Los Angeles,,Cultural / Faith Based Organization,Volunteer operations,,,,US,http://www.catholiccharitiesla.org,,, +California Southern Baptist Convention Disaster Relief,,Cultural / Faith Based Organization,Volunteer operations,,,,US,http://www.csbc.com/disasterrelief,,, +Faithful Central Bible Church,,Cultural / Faith Based Organization,Volunteer operations,,,,US,http://www.faithfulcentral.com,,, +LA Regional Food Bank,,Community,Food safety and security,,,,US,http://www.lafoodbank.org,,, +Lutheran Social Services of the Southwest,,Cultural / Faith Based Organization,,,,,US,http://www.lss-sw.org,,, +"Operation HOPE, Inc.",,Community,Organizational or community preparedness,,,,US,http://www.operationhope.org,,, +Tzu Chi Foundation,,Cultural / Faith Based Organization,Volunteer operations,Health and Mental Health,Health Clinics,,US,http://www.us.tzuchi.org/us/en/,,, +United Way - Los Angeles,,Community,Organizational or community preparedness,,,,US,http://www.unitedwayla.org,,, +Los Angeles City Department of Animal Services,,Government,Animal services,,,,US,http://www.laanimalservices.com,,, +Los Angeles County Chief Information Office,,Government,,,,,US,http://egis3.lacounty.gov/egis/,,, +Los Angeles County Department of Public Health,,Government,"Disaster information/risk communication, Notification / mobilization of staff, Pharmacies, Surveillance",,,,US,http://publichealth.lacounty.gov,,, +Los Angeles County Department of Social Services,,Government,Crisis counseling,,,,US,http://www.ladpss.org,,, +Los Angeles County Emergency Management Office,,"Government, Emergency Management",Disaster information/risk communication,,,,US,http://www.lacoa.org,,, +Walmart,,Business,Pharmacies,,,,US,http://www.walmart.com,,, +Make-A-Wish Foundation of Greater Los Angeles,,,,Health and Mental Health,Mental Health Counseling,,US,www.wishla.org,,, +Make-A-Wish Foundation of Greater Los Angeles,,,,Social Services,Donation Services,,US,www.wishla.org,,, diff --git a/private/templates/DRMP/config.py b/private/templates/DRMP/config.py index a0753f6ef1..b8f0594d20 100644 --- a/private/templates/DRMP/config.py +++ b/private/templates/DRMP/config.py @@ -3247,7 +3247,8 @@ def custom_prep(r): table = s3db.org_organisation # Hide fields - table.organisation_type_id.readable = table.organisation_type_id.writable = False + field = s3db.org_organisation_organisation_type.organisation_type_id + field.readable = field.writable = False table.region_id.readable = table.region_id.writable = False table.country.readable = table.country.writable = False table.year.readable = table.year.writable = False diff --git a/private/templates/DRRPP/controllers.py b/private/templates/DRRPP/controllers.py index 269db90543..b8eef5db54 100644 --- a/private/templates/DRRPP/controllers.py +++ b/private/templates/DRRPP/controllers.py @@ -746,18 +746,18 @@ def __call__(self): s3.scripts.append("/%s/static/scripts/S3/s3.dataTables.multi.min.js" % request.application) s3.js_global.append('''S3.dataTablesInstances=[]''') - s3request, field_list = self._regional() - tables.append(self._table("regional", s3request.resource, field_list)) - s3request, field_list = self._groups() - tables.append(self._table("groups", s3request.resource, field_list)) + s3request, list_fields = self._regional() + tables.append(self._table("regional", s3request.resource, list_fields)) + s3request, list_fields = self._groups() + tables.append(self._table("groups", s3request.resource, list_fields)) else: # AJAX call if table == "groups": - s3request, field_list = self._groups() + s3request, list_fields = self._groups() elif table == "regional": - s3request, field_list = self._regional() + s3request, list_fields = self._regional() current.s3db.configure(s3request.resource.tablename, - list_fields = field_list) + list_fields = list_fields) return s3request() return dict(tables=tables) @@ -774,22 +774,21 @@ def _regional(): s3request = s3_request("org", "organisation", extension="aadata") # (FS("project.id") != None) & \ - f = (FS("organisation_type_id$name").anyof(["Regional Organisation", - "Regional Office", - "Regional Center"])) + f = (FS("organisation_type.name").anyof(["Regional Organisation", + "Regional Office", + "Regional Center"])) s3request.resource.add_filter(f) - field_list = [ - "id", - "name", - "acronym", - (T("Type"), "organisation_type_id"), - "website", - "region_id", - "year", - (T("Notes"), "comments"), - ] - return (s3request, field_list) + list_fields = ["id", + "name", + "acronym", + (T("Type"), "organisation_organisation_type.organisation_type_id"), + "website", + "region_id", + "year", + (T("Notes"), "comments"), + ] + return (s3request, list_fields) # ------------------------------------------------------------------------- @staticmethod @@ -808,19 +807,19 @@ def _groups(): s3request = s3_request("org", "organisation", extension="aadata") #(FS("project.id") != None) & \ - f = (FS("organisation_type_id$name").anyof(["Committees/Mechanism/Forum", - "Network"])) + f = (FS("organisation_type.name").anyof(["Committees/Mechanism/Forum", + "Network"])) s3request.resource.add_filter(f) - field_list = ["id", - "name", - "acronym", - (T("Type"), "organisation_type_id"), - "year", - (T("Address"), "address"), - (T("Notes"), "comments"), - ] - return (s3request, field_list) + list_fields = ["id", + "name", + "acronym", + (T("Type"), "organisation_organisation_type.organisation_type_id"), + "year", + (T("Address"), "address"), + (T("Notes"), "comments"), + ] + return (s3request, list_fields) # ------------------------------------------------------------------------- @staticmethod diff --git a/private/templates/EUROSHA/config.py b/private/templates/EUROSHA/config.py index 26d4ed20b8..522c79900d 100644 --- a/private/templates/EUROSHA/config.py +++ b/private/templates/EUROSHA/config.py @@ -83,6 +83,8 @@ def eurosha_realm_entity(table, row): """ Assign a Realm Entity to records + + NB EUROSHA should never use User Organisation (since volunteers editing on behalf of other Orgs) """ tablename = table._tablename @@ -170,30 +172,8 @@ def eurosha_realm_entity(table, row): # Continue to loop through the rest of the default_fks # Fall back to default get_realm_entity function - # EUROSHA should never use User organsiation (since volunteers editing on behalf of other Orgs) - #use_user_organisation = False - ## Suppliers & Partners are owned by the user's organisation - #if realm_entity == 0 and tablename == "org_organisation": - # ott = s3db.org_organisation_type - # row = table[row.id] - # row = db(table.organisation_type_id == ott.id).select(ott.name, - # limitby=(0, 1) - # ).first() - # - # if row and row.name != "Red Cross / Red Crescent": - # use_user_organisation = True - - ## Groups are owned by the user's organisation - #elif tablename in ["pr_group"]: - # use_user_organisation = True - - #user = current.auth.user - #if use_user_organisation and user: - # # @ToDo - this might cause issues if the user's org is different from the realm that gave them permissions to create the Org - # realm_entity = s3db.pr_get_pe_id("org_organisation", - # user.organisation_id) - return realm_entity + settings.auth.realm_entity = eurosha_realm_entity # Set this if there will be multiple areas in which work is being done, @@ -282,7 +262,7 @@ def custom_prep(r): list_fields = ["id", "name", "acronym", - "organisation_type_id", + "organisation_organisation_type.organisation_type_id", (T("Clusters"), "sector.name"), "country", "website" @@ -295,7 +275,13 @@ def custom_prep(r): crud_form = S3SQLCustomForm( "name", "acronym", - "organisation_type_id", + S3SQLInlineLink( + "organisation_type", + field = "organisation_type_id", + label = T("Type"), + multiple = False, + #widget = "hierarchy", + ), "region_id", "country", S3SQLInlineComponentCheckbox( diff --git a/private/templates/IFRC/Demo/project_location.csv b/private/templates/IFRC/Demo/project_location.csv index 91ed78a9b8..409d4f7af8 100644 --- a/private/templates/IFRC/Demo/project_location.csv +++ b/private/templates/IFRC/Demo/project_location.csv @@ -1,4 +1,4 @@ -"Project Name","Activity Types","Country","L1","L2","L3","L4","Lat","Lon","ContactPerson","Comments","Beneficiaries:Individuals","Beneficiaries:Families","Beneficiaries:Pupils","Beneficiaries:Teachers","Beneficiaries:Men","Beneficiaries:Women" +Project Name,Activity Types,Country,L1,L2,L3,L4,Lat,Lon,ContactPerson,Comments,"Beneficiaries:Individuals","Beneficiaries:Families","Beneficiaries:Pupils","Beneficiaries:Teachers","Beneficiaries:Men","Beneficiaries:Women" "Community Based Disaster Management","Community organisation, Capacity Building, CDRT (Community disaster response teams)","Timor-Leste","Baucau","Laga","Soba","Soba","-8.47342","126.59791","Donato,Urbana,donato.urbana@gmail.com,",,152,,,,, "Community Based Disaster Management","Community organisation, Capacity Building, CDRT (Community disaster response teams)","Timor-Leste","Bobonaro","Bobonaro","Lourba","Zobelis","-9.01786","125.35333","Joana,Arriaga,joana.arriaga@yahoo.com,",,421,,,,, "Community Based Disaster Management","Community organisation, Capacity Building, CDRT (Community disaster response teams)","Timor-Leste","Liquiçá","Liquiçá","Dato","Nunturi","-8.64709","125.34227","Francisco,Hendrigue Pinto,francisco.hendriguepinto@hotmail.com,",,453,,,,, diff --git a/private/templates/IFRC/config.py b/private/templates/IFRC/config.py index f80b00e08a..aaf50759bd 100644 --- a/private/templates/IFRC/config.py +++ b/private/templates/IFRC/config.py @@ -153,13 +153,13 @@ def ifrc_realm_entity(table, row): use_user_organisation = False # Suppliers & Partners are owned by the user's organisation if realm_entity == 0 and tablename == "org_organisation": - ott = s3db.org_organisation_type - query = (table.id == row.id) & \ - (table.organisation_type_id == ott.id) - row = db(query).select(ott.name, + ottable = s3db.org_organisation_type + ltable = db.org_organisation_organisation_type + query = (ltable.organisation_id == row.id) & \ + (ltable.organisation_type_id == ottable.id) + row = db(query).select(ottable.name, limitby=(0, 1) ).first() - if row and row.name != "Red Cross / Red Crescent": use_user_organisation = True @@ -319,9 +319,10 @@ def ifrc_realm_entity(table, row): settings.hrm.use_skills = False # ----------------------------------------------------------------------------- -def ns_only(f, required = True, branches = True, updateable=True): +def ns_only(f, required=True, branches=True, updateable=True): """ - Function to configure an organisation_id field to be restricted to just NS/Branch + Function to configure an organisation_id field to be restricted to just + NS/Branch """ # Label @@ -341,6 +342,10 @@ def ns_only(f, required = True, branches = True, updateable=True): # No IFRC prepop done - skip (e.g. testing impacts of CSS changes in this theme) return + ltable = db.org_organisation_organisation_type + rows = db(ltable.organisation_type_id == type_id).select(ltable.organisation_id) + filter_opts = [row.organisation_id for row in rows] + auth = current.auth s3_has_role = auth.s3_has_role Admin = s3_has_role("ADMIN") @@ -379,9 +384,9 @@ def ns_only(f, required = True, branches = True, updateable=True): requires = IS_ONE_OF(db, "org_organisation.id", represent, filterby = "organisation_type_id", - filter_opts = (type_id,), + filter_opts = filter_opts, not_filterby = not_filterby, - not_filter_opts=not_filter_opts, + not_filter_opts = not_filter_opts, updateable = updateable, orderby = "org_organisation.name", sort = True) @@ -389,16 +394,17 @@ def ns_only(f, required = True, branches = True, updateable=True): from gluon import IS_EMPTY_OR requires = IS_EMPTY_OR(requires) f.requires = requires + # Dropdown not Autocomplete f.widget = None + # Comment if Admin or s3_has_role("ORG_ADMIN"): # Need to do import after setting Theme from s3layouts import S3AddResourceLink from s3.s3navigation import S3ScriptItem - add_link = S3AddResourceLink(c="org", - f="organisation", - vars={"organisation.organisation_type_id$name":"Red Cross / Red Crescent"}, + add_link = S3AddResourceLink(c="org", f="organisation", + vars={"organisation_type.name":"Red Cross / Red Crescent"}, label=T("Create National Society"), title=T("National Society"), ) @@ -1182,42 +1188,43 @@ def custom_prep(r): list_fields = ["id", "name", "acronym", - "organisation_type_id", - #(T("Sectors"), "sector.name"), + "organisation_organisation_type.organisation_type_id", "country", "website" ] - type_filter = r.get_vars.get("organisation.organisation_type_id$name", + type_filter = r.get_vars.get("organisation_type.name", None) + type_label = T("Type") if type_filter: type_names = type_filter.split(",") if len(type_names) == 1: # Strip Type from list_fields - list_fields.remove("organisation_type_id") + list_fields.remove("organisation_organisation_type.organisation_type_id") + type_label = "" if type_filter == "Red Cross / Red Crescent": # Modify filter_widgets - filter_widgets = s3db.get_config("org_organisation", "filter_widgets") + filter_widgets = s3db.get_config("org_organisation", + "filter_widgets") # Remove type (always 'RC') filter_widgets.pop(1) # Remove sector (not relevant) filter_widgets.pop(1) # Modify CRUD Strings - ADD_NS = T("Create National Society") s3.crud_strings.org_organisation = Storage( - label_create=ADD_NS, - title_display=T("National Society Details"), - title_list=T("Red Cross & Red Crescent National Societies"), - title_update=T("Edit National Society"), - title_upload=T("Import Red Cross & Red Crescent National Societies"), - label_list_button=T("List Red Cross & Red Crescent National Societies"), - label_delete_button=T("Delete National Society"), - msg_record_created=T("National Society added"), - msg_record_modified=T("National Society updated"), - msg_record_deleted=T("National Society deleted"), - msg_list_empty=T("No Red Cross & Red Crescent National Societies currently registered") + label_create = T("Create National Society"), + title_display = T("National Society Details"), + title_list = T("Red Cross & Red Crescent National Societies"), + title_update = T("Edit National Society"), + title_upload = T("Import Red Cross & Red Crescent National Societies"), + label_list_button = T("List Red Cross & Red Crescent National Societies"), + label_delete_button = T("Delete National Society"), + msg_record_created = T("National Society added"), + msg_record_modified = T("National Society updated"), + msg_record_deleted = T("National Society deleted"), + msg_list_empty = T("No Red Cross & Red Crescent National Societies currently registered") ) # Add Region to list_fields list_fields.insert(-1, "region_id") @@ -1232,19 +1239,19 @@ def custom_prep(r): if r.interactive: r.table.country.label = T("Country") - from s3.s3forms import S3SQLCustomForm#, S3SQLInlineComponentCheckbox + from s3.s3forms import S3SQLCustomForm, S3SQLInlineLink crud_form = S3SQLCustomForm( "name", "acronym", - "organisation_type_id", + S3SQLInlineLink( + "organisation_type", + field = "organisation_type_id", + label = type_label, + multiple = False, + #widget = "hierarchy", + ), "region_id", "country", - #S3SQLInlineComponentCheckbox( - # "sector", - # label = T("Sectors"), - # field = "sector_id", - # cols = 3, - #), "phone", "website", "logo", @@ -1761,6 +1768,7 @@ def customise_project_project_controller(**attr): "human_resource_id", # Disabled since we need organisation_id filtering to either organisation_type_id == RC or NOT # & also hiding Branches from RCs + # & also rewriting for organisation_type_id via link table # Partner NS # S3SQLInlineComponent( # "organisation", diff --git a/private/templates/IFRC/menus.py b/private/templates/IFRC/menus.py index d324515077..438556b8dc 100644 --- a/private/templates/IFRC/menus.py +++ b/private/templates/IFRC/menus.py @@ -9,7 +9,7 @@ pass import s3menus as default -red_cross_filter = {"organisation.organisation_type_id$name" : "Red Cross / Red Crescent"} +red_cross_filter = {"organisation_type.name" : "Red Cross / Red Crescent"} # ============================================================================= class S3MainMenu(default.S3MainMenu): @@ -312,7 +312,6 @@ def hrm(): M("Staff", c="hrm", f=("staff", "person"), m="summary", check=manager_mode)( M("Create", m="create"), - #M("Search"), M("Import", f="person", m="import", vars=staff, p="create"), ), @@ -322,7 +321,6 @@ def hrm(): M("Teams", c="hrm", f="group", check=manager_mode)( M("Create", m="create"), - #M("Search"), M("Search Members", f="group_membership"), M("Import", f="group_membership", m="import"), ), @@ -333,38 +331,30 @@ def hrm(): M("Create", m="create", vars=red_cross_filter ), - #M("Search", - #vars=red_cross_filter - #), M("Import", m="import", p="create", check=is_org_admin) ), M("Offices", c="org", f="office", check=manager_mode)( M("Create", m="create"), - #M("Search"), M("Import", m="import", p="create"), ), M("Department Catalog", c="hrm", f="department", check=manager_mode)( M("Create", m="create"), - #M("Search"), ), M("Job Title Catalog", c="hrm", f="job_title", check=manager_mode)( M("Create", m="create"), - #M("Search"), M("Import", m="import", p="create", check=is_org_admin), ), #M("Skill Catalog", f="skill", # check=manager_mode)( # M("Create", m="create"), - # #M("Search"), # #M("Skill Provisions", f="skill_provision"), #), M("Training Events", c="hrm", f="training_event", check=manager_mode)( M("Create", m="create"), - #M("Search"), M("Search Training Participants", f="training"), M("Import Participant List", f="training", m="import"), ), @@ -378,14 +368,12 @@ def hrm(): M("Training Course Catalog", c="hrm", f="course", check=manager_mode)( M("Create", m="create"), - #M("Search"), M("Import", m="import", p="create", check=is_org_admin), M("Course Certificates", f="course_certificate"), ), M("Certificate Catalog", c="hrm", f="certificate", check=manager_mode)( M("Create", m="create"), - #M("Search"), M("Import", m="import", p="create", check=is_org_admin), #M("Skill Equivalence", f="certificate_skill"), ), @@ -393,19 +381,16 @@ def hrm(): restrict=[ADMIN], check=manager_mode)( M("Create", m="create"), - #M("Search"), ), M("Office Types", c="org", f="office_type", restrict=[ADMIN], check=manager_mode)( M("Create", m="create"), - #M("Search"), ), #M("Facility Types", c="org", f="facility_type", # restrict=[ADMIN], # check=manager_mode)( # M("Create", m="create"), - # #M("Search"), #), #M("My Profile", c="hrm", f="person", # check=personal_mode, vars=dict(mode="personal")), @@ -463,7 +448,6 @@ def vol(): M("Volunteers", f="volunteer", m="summary", check=[manager_mode])( M("Create", m="create"), - #M("Search"), M("Import", f="person", m="import", vars={"group":"volunteer"}, p="create"), ), @@ -473,74 +457,62 @@ def vol(): M(teams, f="group", check=[manager_mode, use_teams])( M("Create", m="create"), - #M("Search"), M("Search Members", f="group_membership"), M("Import", f="group_membership", m="import"), ), #M("Department Catalog", f="department", # check=manager_mode)( # M("Create", m="create"), - # #M("Search"), #), M("Volunteer Role Catalog", f="job_title", check=[manager_mode, not_vnrc])( M("Create", m="create"), - #M("Search"), M("Import", m="import", p="create", check=is_org_admin), ), M("Skill Catalog", f="skill", check=[manager_mode, skills_menu])( M("Create", m="create"), - #M("Search"), #M("Skill Provisions", f="skill_provision"), ), M("Training Events", f="training_event", check=manager_mode)( M("Create", m="create"), - #M("Search"), M("Search Training Participants", f="training"), M("Import Participant List", f="training", m="import"), ), M("Training Course Catalog", f="course", check=manager_mode)( M("Create", m="create"), - #M("Search"), #M("Course Certificates", f="course_certificate"), ), M("Certificate Catalog", f="certificate", check=manager_mode)( M("Create", m="create"), - #M("Search"), #M("Skill Equivalence", f="certificate_skill"), ), M("Programs", f="programme", check=[manager_mode, show_programmes])( M("Create", m="create"), - #M("Search"), M("Import Hours", f="programme_hours", m="import"), ), M("Awards", f="award", check=[manager_mode, is_org_admin])( M("Create", m="create"), - #M("Search"), ), M("Volunteer Cluster Type", f="cluster_type", check = check_org_dependent_field("vol_volunteer_cluster", "vol_cluster_type_id"))( M("Create", m="create"), - #M("Search"), ), M("Volunteer Cluster", f="cluster", check = check_org_dependent_field("vol_volunteer_cluster", "vol_cluster_id"))( M("Create", m="create"), - #M("Search"), ), M("Volunteer Cluster Position", f="cluster_position", check = check_org_dependent_field("vol_volunteer_cluster", "vol_cluster_position_id"))( M("Create", m="create"), - #M("Search"), ), M("Reports", f="volunteer", m="report", check=manager_mode)( @@ -606,11 +578,9 @@ def use_adjust(i): #M("Home", f="index"), M("Warehouses", c="inv", f="warehouse")( M("Create", m="create"), - #M("Search"), M("Import", m="import", p="create"), ), M("Warehouse Stock", c="inv", f="inv_item")( - #M("Search", f="inv_item"), M("Search Shipped Items", f="track_item"), M("Adjust Stock Levels", f="adj", check=use_adjust), #M("Kitting", f="kit"), @@ -631,58 +601,46 @@ def use_adjust(i): ), M(inv_recv_list, c="inv", f="recv")( M("Create", m="create"), - #M("Search"), ), M("Sent Shipments", c="inv", f="send")( M("Create", m="create"), - #M("Search"), M("Search Shipped Items", f="track_item"), ), M("Items", c="supply", f="item", m="summary")( M("Create", m="create"), - #M("Search"), M("Import", f="catalog_item", m="import", p="create"), ), # Catalog Items moved to be next to the Item Categories #M("Catalog Items", c="supply", f="catalog_item")( # M("Create", m="create"), - # #M("Search"), #), #M("Brands", c="supply", f="brand", # restrict=[ADMIN])( # M("Create", m="create"), - # #M("Search"), #), M("Catalogs", c="supply", f="catalog")( M("Create", m="create"), - #M("Search"), ), M("Item Categories", c="supply", f="item_category", restrict=[ADMIN])( M("Create", m="create"), - #M("Search"), ), M("Suppliers", c="inv", f="supplier")( M("Create", m="create"), - #M("Search"), M("Import", m="import", p="create"), ), M("Facilities", c="inv", f="facility")( M("Create", m="create", t="org_facility"), - #M("Search"), ), M("Facility Types", c="inv", f="facility_type", restrict=[ADMIN])( M("Create", m="create"), - #M("Search"), ), M("Requests", c="req", f="req")( M("Create", m="create"), - #M("Search"), M("Requested Items", f="req_item"), ), M("Commitments", c="req", f="commit", check=use_commit)( - #M("Search") ), ) @@ -701,11 +659,9 @@ def irs(): return M()( M("Events", c="event", f="event")( M("Create", m="create"), - #M("Search"), ), M("Incident Reports", c="irs", f="ireport")( M("Create", m="create"), - #M("Search"), M("Open Incidents", vars={"open": 1}), M("Map", m="map"), M("Timeline", args="timeline"), @@ -714,7 +670,6 @@ def irs(): M("Incident Categories", c="irs", f="icategory", check=current.auth.s3_has_role(current.session.s3.system_roles.ADMIN))( M("Create", m="create"), - #M("Search"), ), M("Reports", c="irs", f="ireport", m="report")( M("Incidents", m="report"), diff --git a/private/templates/India/config.py b/private/templates/India/config.py index 1e84ec5e27..fdb0fb4f40 100644 --- a/private/templates/India/config.py +++ b/private/templates/India/config.py @@ -3152,7 +3152,8 @@ def custom_prep(r): table = s3db.org_organisation # Hide fields - table.organisation_type_id.readable = table.organisation_type_id.writable = False + field = s3db.org_organisation_organisation_type.organisation_type_id + field.readable = field.writable = False table.region_id.readable = table.region_id.writable = False table.country.readable = table.country.writable = False table.year.readable = table.year.writable = False diff --git a/private/templates/LK/config.py b/private/templates/LK/config.py index 12afdf3eea..9da3abe275 100644 --- a/private/templates/LK/config.py +++ b/private/templates/LK/config.py @@ -3288,7 +3288,8 @@ def custom_prep(r): table = s3db.org_organisation # Hide fields - table.organisation_type_id.readable = table.organisation_type_id.writable = False + field = s3db.org_organisation_organisation_type.organisation_type_id + field.readable = field.writable = False table.region_id.readable = table.region_id.writable = False table.country.readable = table.country.writable = False table.year.readable = table.year.writable = False diff --git a/private/templates/MCOP/config.py b/private/templates/MCOP/config.py index b31bc187c3..a3d5d0b440 100644 --- a/private/templates/MCOP/config.py +++ b/private/templates/MCOP/config.py @@ -485,8 +485,6 @@ def customise_event_incident_resource(r, tablename): S3OptionsFilter("organisation_id", represent = "%(name)s", ), - #S3OptionsFilter("project_organisation.organisation_id$organisation_type_id", - # ), ] url_next = URL(c="event", f="incident", args=["[id]", "profile"]) @@ -700,10 +698,16 @@ def customise_org_organisation_resource(r, tablename): msg_record_deleted = T("Stakeholder deleted"), msg_list_empty = T("No Stakeholders currently registered")) - from s3.s3forms import S3SQLCustomForm + from s3.s3forms import S3SQLCustomForm, S3SQLInlineLink crud_form = S3SQLCustomForm("id", "name", - "organisation_type_id", + S3SQLInlineLink( + "organisation_type", + field = "organisation_type_id", + label = T("Type"), + multiple = False, + #widget = "hierarchy", + ), "logo", "phone", "website", @@ -727,7 +731,7 @@ def customise_org_organisation_resource(r, tablename): "comments", ], label = T("Search")), - S3OptionsFilter("organisation_type_id", + S3OptionsFilter("organisation_organisation_type.organisation_type_id", label = T("Type"), ), ] diff --git a/private/templates/NEREIDS/config.py b/private/templates/NEREIDS/config.py index 7ba8464ebb..d6fbce92fa 100644 --- a/private/templates/NEREIDS/config.py +++ b/private/templates/NEREIDS/config.py @@ -2918,7 +2918,8 @@ def custom_prep(r): table = s3db.org_organisation # Hide fields - table.organisation_type_id.readable = table.organisation_type_id.writable = False + field = s3db.org_organisation_organisation_type.organisation_type_id + field.readable = field.writable = False table.region_id.readable = table.region_id.writable = False table.country.readable = table.country.writable = False table.year.readable = table.year.writable = False diff --git a/private/templates/NYC/config.py b/private/templates/NYC/config.py index c0e133f938..5f4fff700b 100644 --- a/private/templates/NYC/config.py +++ b/private/templates/NYC/config.py @@ -394,7 +394,7 @@ def custom_prep(r): list_fields = ["id", "name", "acronym", - "organisation_type_id", + "organisation_organisation_type.organisation_type_id", (T("Services"), "service.name"), (T("Neighborhoods Served"), "location.name"), ] @@ -405,13 +405,17 @@ def custom_prep(r): if r.interactive: if not r.component: from gluon.html import DIV, INPUT - from s3.s3forms import S3SQLCustomForm, S3SQLInlineComponent, S3SQLInlineComponentMultiSelectWidget - # activate hierarchical org_service: - #from s3 import S3SQLCustomForm, S3SQLInlineComponent, S3SQLInlineComponentMultiSelectWidget, S3SQLInlineLink + from s3.s3forms import S3SQLCustomForm, S3SQLInlineLink, S3SQLInlineComponent, S3SQLInlineComponentMultiSelectWidget crud_form = S3SQLCustomForm( "name", "acronym", - "organisation_type_id", + S3SQLInlineLink( + "organisation_type", + field = "organisation_type_id", + label = T("Type"), + multiple = False, + #widget = "hierarchy", + ), S3SQLInlineComponentMultiSelectWidget( # activate hierarchical org_service: #S3SQLInlineLink( @@ -550,7 +554,7 @@ def custom_prep(r): # #label = T("Service"), # #hidden = True, # ), - S3OptionsFilter("organisation_type_id", + S3OptionsFilter("organisation_organisation_type.organisation_type_id", label = T("Type"), #hidden = True, ), diff --git a/private/templates/OCHA/config.py b/private/templates/OCHA/config.py index 764e9e0fa9..a6b361994f 100644 --- a/private/templates/OCHA/config.py +++ b/private/templates/OCHA/config.py @@ -226,7 +226,7 @@ def custom_prep(r): list_fields = ["id", "name", "acronym", - "organisation_type_id", + "organisation_organisation_type.organisation_type_id", (T("Clusters"), "sector.name"), "country", "website" @@ -239,7 +239,13 @@ def custom_prep(r): crud_form = S3SQLCustomForm( "name", "acronym", - "organisation_type_id", + S3SQLInlineLink( + "organisation_type", + field = "organisation_type_id", + label = T("Type"), + multiple = False, + #widget = "hierarchy", + ), "region_id", "country", S3SQLInlineComponentCheckbox( @@ -257,40 +263,29 @@ def custom_prep(r): from s3.s3filter import S3TextFilter, S3OptionsFilter, S3LocationFilter filter_widgets = [ S3TextFilter(["name", "acronym"], - label=T("Name"), - _class="filter-search", + label = T("Name"), + _class = "filter-search", ), - S3OptionsFilter("organisation_type_id", - label=T("Type"), - represent="%(name)s", - widget="multiselect", - cols=3, - #hidden=True, + S3OptionsFilter("organisation_organisation_type.organisation_type_id", + label = T("Type"), + #hidden = True, ), S3OptionsFilter("sector_organisation.sector_id", - label=T("Cluster"), - represent="%(name)s", - widget="multiselect", - cols=3, - #hidden=True, + label = T("Cluster"), + #hidden = True, ), S3OptionsFilter("project_organisation.project_id$theme_project.theme_id", - label=T("Theme"), - represent="%(name)s", - widget="multiselect", - cols=3, - #hidden=True, + label = T("Theme"), + #hidden = True, ), S3LocationFilter("project_organisation.project_id$location.location_id", - label=T("Location"), - levels=["L1", "L2"], - widget="multiselect", - cols=3, - #hidden=True, + label = T("Location"), + levels = ["L1", "L2"], + #hidden = True, ), ] s3db.configure("org_organisation", - crud_form=crud_form, + crud_form = crud_form, filter_widgets = filter_widgets, ) diff --git a/private/templates/Philippines/config.py b/private/templates/Philippines/config.py index 06440ae183..6d9cae0a5b 100644 --- a/private/templates/Philippines/config.py +++ b/private/templates/Philippines/config.py @@ -2404,14 +2404,15 @@ def custom_prep(r): ntable = s3db.req_organisation_needs s3db.configure("org_organisation", - filter_widgets=filter_widgets + filter_widgets = filter_widgets ) # Represent used in rendering current.auth.settings.table_user.organisation_id.represent = s3db.org_organisation_represent # Hide fields - table.organisation_type_id.readable = table.organisation_type_id.writable = False + field = s3db.org_organisation_organisation_type.organisation_type_id + field.readable = field.writable = False table.region_id.readable = table.region_id.writable = False table.country.readable = table.country.writable = False table.year.readable = table.year.writable = False diff --git a/private/templates/SandyRelief/config.py b/private/templates/SandyRelief/config.py index 8a22461a91..255f6dee83 100644 --- a/private/templates/SandyRelief/config.py +++ b/private/templates/SandyRelief/config.py @@ -258,29 +258,33 @@ def custom_prep(r): list_fields = ["id", "name", "acronym", - "organisation_type_id", + "organisation_organisation_type.organisation_type_id", (T("Services"), "service.name"), (T("Neighborhoods Served"), "location.name"), ] s3db.configure("org_organisation", list_fields=list_fields) if r.interactive: - from s3.s3forms import S3SQLCustomForm, S3SQLInlineComponent, S3SQLInlineComponentMultiSelectWidget + from s3.s3forms import S3SQLCustomForm, S3SQLInlineLink, S3SQLInlineComponent, S3SQLInlineComponentMultiSelectWidget s3db.pr_address.comments.label = "" s3db.pr_contact.value.label = "" s3db.doc_document.url.label = "" crud_form = S3SQLCustomForm( "name", "acronym", - "organisation_type_id", - #S3SQLInlineComponentCheckbox( + S3SQLInlineLink( + "organisation_type", + field = "organisation_type_id", + label = T("Type"), + multiple = False, + #widget = "hierarchy", + ), S3SQLInlineComponentMultiSelectWidget( "service", label = T("Services"), field = "service_id", cols = 4, ), - #S3SQLInlineComponentCheckbox( S3SQLInlineComponentMultiSelectWidget( "group", label = T("Network"), @@ -386,36 +390,26 @@ def custom_prep(r): from s3.s3filter import S3LocationFilter, S3OptionsFilter, S3TextFilter filter_widgets = [ S3TextFilter(["name", "acronym"], - label=T("Name"), - _class="filter-search", + label = T("Name"), + _class = "filter-search", ), S3OptionsFilter("group_membership.group_id", - label=T("Network"), - represent="%(name)s", - widget="multiselect", - cols=3, - #hidden=True, + label = T("Network"), + represent = "%(name)s", + #hidden = True, ), S3LocationFilter("organisation_location.location_id", - label=T("Neighborhood"), - levels=["L3", "L4"], - widget="multiselect", - cols=3, - #hidden=True, + label = T("Neighborhood"), + levels = ["L3", "L4"], + #hidden = True, ), S3OptionsFilter("service_organisation.service_id", - label=T("Service"), - represent="%(name)s", - widget="multiselect", - cols=3, - #hidden=True, + label = T("Service"), + #hidden = True, ), - S3OptionsFilter("organisation_type_id", - label=T("Type"), - represent="%(name)s", - widget="multiselect", - cols=3, - #hidden=True, + S3OptionsFilter("organisation_organisation_type.organisation_type_id", + label = T("Type"), + #hidden = True, ), ] diff --git a/private/templates/Syria/config.py b/private/templates/Syria/config.py index b525f1feeb..191fd87d89 100644 --- a/private/templates/Syria/config.py +++ b/private/templates/Syria/config.py @@ -951,7 +951,8 @@ def custom_prep(r): table = s3db.org_organisation # Hide fields - table.organisation_type_id.readable = table.organisation_type_id.writable = False + field = s3db.org_organisation_organisation_type.organisation_type_id + field.readable = field.writable = False table.region_id.readable = table.region_id.writable = False table.country.readable = table.country.writable = False table.year.readable = table.year.writable = False diff --git a/private/templates/Yolanda/config.py b/private/templates/Yolanda/config.py index 8dfc5d61c2..71870ee17f 100644 --- a/private/templates/Yolanda/config.py +++ b/private/templates/Yolanda/config.py @@ -17,7 +17,7 @@ from s3.s3utils import S3DateTime, s3_auth_user_represent_name, s3_avatar_represent from s3.s3validators import IS_LOCATION_SELECTOR2, IS_ONE_OF from s3.s3widgets import S3LocationSelectorWidget2 -from s3.s3forms import S3SQLCustomForm, S3SQLInlineComponent, S3SQLInlineComponentMultiSelectWidget +from s3.s3forms import S3SQLCustomForm, S3SQLInlineLink, S3SQLInlineComponent, S3SQLInlineComponentMultiSelectWidget T = current.T s3 = current.response.s3 @@ -2366,7 +2366,7 @@ def custom_prep(r): "comments", ], label = T("Search")), - S3OptionsFilter("organisation_type_id", + S3OptionsFilter("organisation_organisation_type.organisation_type_id", label = T("Type"), ), ] @@ -2389,7 +2389,13 @@ def custom_prep(r): s3_sql_custom_fields = ["id", "name", - "organisation_type_id", + S3SQLInlineLink( + "organisation_type", + field = "organisation_type_id", + label = T("Type"), + multiple = False, + #widget = "hierarchy", + ), "country", S3SQLInlineComponentMultiSelectWidget( "sector", @@ -3243,7 +3249,7 @@ def custom_prep(r): S3OptionsFilter("activity_organisation.organisation_id", represent = "%(name)s", ), - S3OptionsFilter("activity_organisation.organisation_id$organisation_type_id", + S3OptionsFilter("activity_organisation.organisation_id$organisation_organisation_type.organisation_type_id", # Doesn't support translation #represent = "%(name)s", ), diff --git a/private/templates/Yolanda/gis_layer_feature.csv b/private/templates/Yolanda/gis_layer_feature.csv index 88ecb53a63..3e018f80e3 100644 --- a/private/templates/Yolanda/gis_layer_feature.csv +++ b/private/templates/Yolanda/gis_layer_feature.csv @@ -1,6 +1,6 @@ Name,Description,Controller,Function,Symbology,Marker,GPS Marker,Popup Label,Popup Fields,Attributes,Filter,Polygons,Site,Style,Folder,Visible,Enabled,Cluster Threshold,Refresh "Aid Deliveries",,"project","activity","OCHA","project",,,"name,organisaton_id,location_id,distribution.parameter_id,beneficiary.value",,,,,"[{'prop':'sector_id','cat':'WASH/WATSAN','externalGraphic':'img/markers/OCHA/cluster_WASH_40px.png'},{'prop':'sector_id','cat':'Food Security/Nutrition/Livelihood','externalGraphic':'img/markers/OCHA/cluster_food_security_40px.png'},{'prop':'sector_id','cat':'Shelter/Settlement/NFI','externalGraphic':'img/markers/OCHA/cluster_shelter_40px.png'},{'prop':'sector_id','cat':'Health','externalGraphic':'img/markers/OCHA/cluster_health_40px.png'},{'prop':'sector_id','cat':'Protection','externalGraphic':'img/markers/OCHA/cluster_protection_40px.png'},{'prop':'sector_id','cat':'Relief','externalGraphic':'img/markers/OCHA/activity_response_40px.png'},{'prop':'sector_id','cat':'Capacity Building','externalGraphic':'img/markers/OCHA/activity_training_40px.png'},{'prop':'sector_id','cat':'Logistics','externalGraphic':'img/markers/OCHA/cluster_logistics_40px.png'}]",,"False",,, -"Aid Deliveries (Company)",,"project","activity","OCHA","project",,,"name,organisaton_id,location_id,distribution.parameter_id,beneficiary.value",,"activity_organisation.organisation_id$organisation_type_id$name=Company",,,"[{'prop':'sector_id','cat':'WASH/WATSAN','externalGraphic':'img/markers/OCHA/cluster_WASH_40px.png'},{'prop':'sector_id','cat':'Food Security/Nutrition/Livelihood','externalGraphic':'img/markers/OCHA/cluster_food_security_40px.png'},{'prop':'sector_id','cat':'Shelter/Settlement/NFI','externalGraphic':'img/markers/OCHA/cluster_shelter_40px.png'},{'prop':'sector_id','cat':'Health','externalGraphic':'img/markers/OCHA/cluster_health_40px.png'},{'prop':'sector_id','cat':'Protection','externalGraphic':'img/markers/OCHA/cluster_protection_40px.png'},{'prop':'sector_id','cat':'Relief','externalGraphic':'img/markers/OCHA/activity_response_40px.png'},{'prop':'sector_id','cat':'Capacity Building','externalGraphic':'img/markers/OCHA/activity_training_40px.png'},{'prop':'sector_id','cat':'Logistics','externalGraphic':'img/markers/OCHA/cluster_logistics_40px.png'}]",,"False",,, +"Aid Deliveries (Company)",,"project","activity","OCHA","project",,,"name,organisaton_id,location_id,distribution.parameter_id,beneficiary.value",,"organisation_type.name=Company",,,"[{'prop':'sector_id','cat':'WASH/WATSAN','externalGraphic':'img/markers/OCHA/cluster_WASH_40px.png'},{'prop':'sector_id','cat':'Food Security/Nutrition/Livelihood','externalGraphic':'img/markers/OCHA/cluster_food_security_40px.png'},{'prop':'sector_id','cat':'Shelter/Settlement/NFI','externalGraphic':'img/markers/OCHA/cluster_shelter_40px.png'},{'prop':'sector_id','cat':'Health','externalGraphic':'img/markers/OCHA/cluster_health_40px.png'},{'prop':'sector_id','cat':'Protection','externalGraphic':'img/markers/OCHA/cluster_protection_40px.png'},{'prop':'sector_id','cat':'Relief','externalGraphic':'img/markers/OCHA/activity_response_40px.png'},{'prop':'sector_id','cat':'Capacity Building','externalGraphic':'img/markers/OCHA/activity_training_40px.png'},{'prop':'sector_id','cat':'Logistics','externalGraphic':'img/markers/OCHA/cluster_logistics_40px.png'}]",,"False",,, Areas of Intervention,,project,location,,,,,"project_id,location_id","project_id",,True,,"[{'prop':'project_id','cat':'I','fill':'a6cee3','fillOpacity':0.5},{'prop':'project_id','cat':'II','fill':'1f78b4','fillOpacity':0.5},{'prop':'project_id','cat':'III','fill':'b2df8a','fillOpacity':0.5},{'prop':'project_id','cat':'IV','fill':'33a02c','fillOpacity':0.5},{'prop':'project_id','cat':'V','fill':'fb9a99','fillOpacity':0.5},{'prop':'project_id','cat':'VI','fill':'e31a1c','fillOpacity':0.5},{'prop':'project_id','cat':'VII','fill':'fdbf6f','fillOpacity':0.5},{'prop':'project_id','cat':'VIII','fill':'ff7f00','fillOpacity':0.5},{'prop':'project_id','cat':'IX','fill':'cab2d6','fillOpacity':0.5},{'prop':'project_id','cat':'X','fill':'6a3d9a','fillOpacity':0.5},{'prop':'project_id','cat':'XI','fill':'ffff99','fillOpacity':0.5},{'prop':'project_id','cat':'XII','fill':'b15928','fillOpacity':0.5},{'prop':'project_id','cat':'XIII','fill':'a6cee3','fillOpacity':0.5},{'prop':'project_id','cat':'XIV','fill':'1f78b4','fillOpacity':0.5},{'prop':'project_id','cat':'XV','fill':'b2df8a','fillOpacity':0.5},{'prop':'project_id','cat':'XVI','fill':'33a02c','fillOpacity':0.5},{'prop':'project_id','cat':'XVII','fill':'fb9a99','fillOpacity':0.5},{'prop':'project_id','cat':'XVIII','fill':'ff7f00','fillOpacity':0.5},{'prop':'project_id','cat':'XIX','fill':'cab2d6','fillOpacity':0.5},{'prop':'project_id','cat':'XX','fill':'6a3d9a','fillOpacity':0.5},{'prop':'project_id','cat':'XXI','fill':'ffff99','fillOpacity':0.5},{'prop':'project_id','cat':'XXII','fill':'ffff99','fillOpacity':0.5},{'prop':'project_id','cat':'XXIII','fill':'b15928','fillOpacity':0.5},{'prop':'project_id','cat':'XXIV','fill':'a6cee3','fillOpacity':0.5},{'prop':'project_id','cat':'XXV','fill':'1f78b4','fillOpacity':0.5},{'prop':'project_id','cat':'XXVI','fill':'b2df8a','fillOpacity':0.5}]",,False,,0, Donations,,req,commit,OCHA,distribution,Car,Donation,"organisation_id,person_id,comments,date_available",,~.cancel=False,,,,,False,, Requests,,req,req,OCHA,beneficiary,Flag,Request,"site_id,purpose,date",,"~.req_status=0,1",,True,,,False,, diff --git a/private/templates/default/config.py b/private/templates/default/config.py index c5b9a05351..1ee0dfdf83 100644 --- a/private/templates/default/config.py +++ b/private/templates/default/config.py @@ -445,6 +445,10 @@ # Enable the use of Organisation Groups & what their name is #settings.org.groups = "Coalition" #settings.org.groups = "Network" +# Make Organisation Types Hierarchical +#settings.org.organisation_types_hierarchical = True +# Make Organisation Types Multiple +#settings.org.organisation_types_multiple = True # Enable the use of Organisation Regions #settings.org.regions = True # Make Organisation Regions Hierarchical diff --git a/static/formats/drrp.xsl b/static/formats/drrp.xsl index 62ed0909c8..63cfd64467 100644 --- a/static/formats/drrp.xsl +++ b/static/formats/drrp.xsl @@ -588,16 +588,18 @@ - - - - OrgType:Network - - - OrgType:Committees/Mechanism/Forum - - - + + + + + OrgType:Network + + + OrgType:Committees/Mechanism/Forum + + + + @@ -696,19 +698,21 @@ - - - - OrgType:Regional Office - - - OrgType:Regional Organisation - - - OrgType:Regional Center - - - + + + + + OrgType:Regional Office + + + OrgType:Regional Organisation + + + OrgType:Regional Center + + + + diff --git a/static/formats/s3csv/org/organisation.xsl b/static/formats/s3csv/org/organisation.xsl index 39ce97a305..4ee23aee77 100644 --- a/static/formats/s3csv/org/organisation.xsl +++ b/static/formats/s3csv/org/organisation.xsl @@ -12,7 +12,9 @@ all of the following are for the branch, unless the branch field is empty: Acronym.................org_organisation.acronym - Type....................org_organisation$organisation_type_id + Type....................org_organisation$organisation_type_id or org_organisation_type.parent + SubType.................org_organisation$organisation_type_id or org_organisation_type.parent + SubSubType..............org_organisation$organisation_type_id Sectors.................org_sector_organisation$sector_id Services................org_service_organisation$service_id Region..................org_organisation.region_id @@ -31,19 +33,35 @@ + + - + - - + + + + + + + + + + + + @@ -92,6 +110,15 @@ + + + + + + + + + @@ -120,12 +147,28 @@ - - - - - - + + + + + + + + + + + + + + + + + + + + + + @@ -236,14 +279,43 @@ - + + + + + + + + + + + - + - + + + + + + + + + + + + + + + + + + + + diff --git a/static/formats/s3csv/project/organisation.xsl b/static/formats/s3csv/project/organisation.xsl index aa35fc8416..ba98a19f03 100644 --- a/static/formats/s3csv/project/organisation.xsl +++ b/static/formats/s3csv/project/organisation.xsl @@ -134,21 +134,23 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + + +