Add basic CRUD for Person "preferred first name"
only shown if config flag says so
This commit is contained in:
		
							parent
							
								
									cdc857065b
								
							
						
					
					
						commit
						1889f7d269
					
				
					 3 changed files with 91 additions and 17 deletions
				
			
		|  | @ -5,6 +5,9 @@ CHANGELOG | |||
| Unreleased | ||||
| ---------- | ||||
| 
 | ||||
| * Add basic CRUD for Person "preferred first name". | ||||
| 
 | ||||
| 
 | ||||
| 0.9.89 (2024-03-27) | ||||
| ------------------- | ||||
| 
 | ||||
|  |  | |||
|  | @ -91,6 +91,12 @@ | |||
|               <span>{{ person.first_name }}</span> | ||||
|             </b-field> | ||||
| 
 | ||||
|             % if use_preferred_first_name: | ||||
|                 <b-field horizontal label="Preferred First Name"> | ||||
|                   <span>{{ person.preferred_first_name }}</span> | ||||
|                 </b-field> | ||||
|             % endif | ||||
| 
 | ||||
|             <b-field horizontal label="Middle Name"> | ||||
|               <span>{{ person.middle_name }}</span> | ||||
|             </b-field> | ||||
|  | @ -118,11 +124,25 @@ | |||
|                   </header> | ||||
| 
 | ||||
|                   <section class="modal-card-body"> | ||||
|                     <b-field label="First Name"> | ||||
|                       <b-input v-model.trim="editNameFirst" | ||||
|                                :maxlength="maxLengths.person_first_name || null"> | ||||
|                       </b-input> | ||||
| 
 | ||||
|                     <b-field grouped> | ||||
| 
 | ||||
|                       <b-field label="First Name" expanded> | ||||
|                         <b-input v-model.trim="editNameFirst" | ||||
|                                  :maxlength="maxLengths.person_first_name || null"> | ||||
|                         </b-input> | ||||
|                       </b-field> | ||||
| 
 | ||||
|                       % if use_preferred_first_name: | ||||
|                           <b-field label="Preferred First Name" expanded> | ||||
|                             <b-input v-model.trim="editNameFirstPreferred" | ||||
|                                      :maxlength="maxLengths.person_preferred_first_name || null"> | ||||
|                             </b-input> | ||||
|                           </b-field> | ||||
|                       % endif | ||||
| 
 | ||||
|                     </b-field> | ||||
| 
 | ||||
|                     <b-field label="Middle Name"> | ||||
|                       <b-input v-model.trim="editNameMiddle" | ||||
|                                :maxlength="maxLengths.person_middle_name || null"> | ||||
|  | @ -1497,6 +1517,9 @@ | |||
|         % if request.has_perm('people_profile.edit_person'): | ||||
|             editNameShowDialog: false, | ||||
|             editNameFirst: null, | ||||
|             % if use_preferred_first_name: | ||||
|                 editNameFirstPreferred: null, | ||||
|             % endif | ||||
|             editNameMiddle: null, | ||||
|             editNameLast: null, | ||||
| 
 | ||||
|  | @ -1590,6 +1613,9 @@ | |||
| 
 | ||||
|                 editNameInit() { | ||||
|                     this.editNameFirst = this.person.first_name | ||||
|                     % if use_preferred_first_name: | ||||
|                         this.editNameFirstPreferred = this.person.preferred_first_name | ||||
|                     % endif | ||||
|                     this.editNameMiddle = this.person.middle_name | ||||
|                     this.editNameLast = this.person.last_name | ||||
|                     this.editNameShowDialog = true | ||||
|  | @ -1599,6 +1625,9 @@ | |||
|                     let url = '${url('people.profile_edit_name', uuid=person.uuid)}' | ||||
|                     let params = { | ||||
|                         first_name: this.editNameFirst, | ||||
|                         % if use_preferred_first_name: | ||||
|                             preferred_first_name: this.editNameFirstPreferred, | ||||
|                         % endif | ||||
|                         middle_name: this.editNameMiddle, | ||||
|                         last_name: this.editNameLast, | ||||
|                     } | ||||
|  |  | |||
|  | @ -2,7 +2,7 @@ | |||
| ################################################################################ | ||||
| # | ||||
| #  Rattail -- Retail Software Framework | ||||
| #  Copyright © 2010-2023 Lance Edgar | ||||
| #  Copyright © 2010-2024 Lance Edgar | ||||
| # | ||||
| #  This file is part of Rattail. | ||||
| # | ||||
|  | @ -32,7 +32,8 @@ import sqlalchemy as sa | |||
| from sqlalchemy import orm | ||||
| import sqlalchemy_continuum as continuum | ||||
| 
 | ||||
| from rattail.db import model, api | ||||
| from rattail.db import api | ||||
| from rattail.db.model import Person, PersonNote, MergePeopleRequest | ||||
| from rattail.db.util import maxlen | ||||
| from rattail.time import localtime | ||||
| from rattail.util import simple_error | ||||
|  | @ -53,7 +54,7 @@ class PersonView(MasterView): | |||
|     """ | ||||
|     Master view for the Person class. | ||||
|     """ | ||||
|     model_class = model.Person | ||||
|     model_class = Person | ||||
|     model_title_plural = "People" | ||||
|     route_prefix = 'people' | ||||
|     touchable = True | ||||
|  | @ -210,6 +211,7 @@ class PersonView(MasterView): | |||
|                             c="MR") | ||||
| 
 | ||||
|     def get_instance(self): | ||||
|         model = self.model | ||||
|         # TODO: I don't recall why this fallback check for a vendor contact | ||||
|         # exists here, but leaving it intact for now. | ||||
|         key = self.request.matchdict['uuid'] | ||||
|  | @ -237,6 +239,13 @@ class PersonView(MasterView): | |||
|             return True | ||||
|         return not self.is_person_protected(person) | ||||
| 
 | ||||
|     def configure_form(self, f): | ||||
|         super().configure_form(f) | ||||
| 
 | ||||
|         # preferred_first_name | ||||
|         if self.people_handler.should_use_preferred_first_name(): | ||||
|             f.insert_after('first_name', 'preferred_first_name') | ||||
| 
 | ||||
|     def objectify(self, form, data=None): | ||||
|         if data is None: | ||||
|             data = form.validated | ||||
|  | @ -248,6 +257,9 @@ class PersonView(MasterView): | |||
|         names = {} | ||||
|         if 'first_name' in form: | ||||
|             names['first'] = data['first_name'] | ||||
|         if self.people_handler.should_use_preferred_first_name(): | ||||
|             if 'preferred_first_name' in form: | ||||
|                 names['preferred_first'] = data['preferred_first_name'] | ||||
|         if 'middle_name' in form: | ||||
|             names['middle'] = data['middle_name'] | ||||
|         if 'last_name' in form: | ||||
|  | @ -292,6 +304,8 @@ class PersonView(MasterView): | |||
|         In addition to "touching" the person proper, we also "touch" each | ||||
|         contact info record associated with them. | ||||
|         """ | ||||
|         model = self.model | ||||
| 
 | ||||
|         # touch person, as per usual | ||||
|         super().touch_instance(person) | ||||
| 
 | ||||
|  | @ -426,6 +440,7 @@ class PersonView(MasterView): | |||
|             return "" | ||||
| 
 | ||||
|     def get_version_child_classes(self): | ||||
|         model = self.model | ||||
|         return [ | ||||
|             (model.PersonPhoneNumber, 'parent_uuid'), | ||||
|             (model.PersonEmailAddress, 'parent_uuid'), | ||||
|  | @ -474,6 +489,7 @@ class PersonView(MasterView): | |||
|             'expose_customer_people': self.customers_should_expose_people(), | ||||
|             'expose_customer_shoppers': self.customers_should_expose_shoppers(), | ||||
|             'max_one_member': app.get_membership_handler().max_one_per_person(), | ||||
|             'use_preferred_first_name': self.people_handler.should_use_preferred_first_name(), | ||||
|         } | ||||
| 
 | ||||
|         if self.request.has_perm('people_profile.view_versions'): | ||||
|  | @ -552,7 +568,7 @@ class PersonView(MasterView): | |||
| 
 | ||||
|     def get_max_lengths(self): | ||||
|         model = self.model | ||||
|         return { | ||||
|         lengths = { | ||||
|             'person_first_name': maxlen(model.Person.first_name), | ||||
|             'person_middle_name': maxlen(model.Person.middle_name), | ||||
|             'person_last_name': maxlen(model.Person.last_name), | ||||
|  | @ -562,6 +578,9 @@ class PersonView(MasterView): | |||
|             'address_state': maxlen(model.PersonMailingAddress.state), | ||||
|             'address_zipcode': maxlen(model.PersonMailingAddress.zipcode), | ||||
|         } | ||||
|         if self.people_handler.should_use_preferred_first_name(): | ||||
|             lengths['person_preferred_first_name'] = maxlen(model.Person.preferred_first_name) | ||||
|         return lengths | ||||
| 
 | ||||
|     def get_phone_type_options(self): | ||||
|         """ | ||||
|  | @ -606,6 +625,9 @@ class PersonView(MasterView): | |||
|             'dynamic_content_title': self.get_context_content_title(person), | ||||
|         } | ||||
| 
 | ||||
|         if self.people_handler.should_use_preferred_first_name(): | ||||
|             context['preferred_first_name'] = person.preferred_first_name | ||||
| 
 | ||||
|         if person.address: | ||||
|             context['address'] = self.get_context_address(person.address) | ||||
| 
 | ||||
|  | @ -871,10 +893,16 @@ class PersonView(MasterView): | |||
|         person = self.get_instance() | ||||
|         data = dict(self.request.json_body) | ||||
| 
 | ||||
|         self.handler.update_names(person, | ||||
|                                   first=data['first_name'], | ||||
|                                   middle=data['middle_name'], | ||||
|                                   last=data['last_name']) | ||||
|         kw = { | ||||
|             'first': data['first_name'], | ||||
|             'middle': data['middle_name'], | ||||
|             'last': data['last_name'], | ||||
|         } | ||||
| 
 | ||||
|         if self.people_handler.should_use_preferred_first_name(): | ||||
|             kw['preferred_first'] = data['preferred_first_name'] | ||||
| 
 | ||||
|         self.handler.update_names(person, **kw) | ||||
| 
 | ||||
|         self.Session.flush() | ||||
|         return self.profile_changed_response(person) | ||||
|  | @ -913,6 +941,7 @@ class PersonView(MasterView): | |||
|         """ | ||||
|         View which updates a phone number for the person. | ||||
|         """ | ||||
|         model = self.model | ||||
|         person = self.get_instance() | ||||
|         data = dict(self.request.json_body) | ||||
| 
 | ||||
|  | @ -940,6 +969,7 @@ class PersonView(MasterView): | |||
|         """ | ||||
|         View which allows a person's phone number to be deleted. | ||||
|         """ | ||||
|         model = self.model | ||||
|         person = self.get_instance() | ||||
|         data = dict(self.request.json_body) | ||||
| 
 | ||||
|  | @ -960,6 +990,7 @@ class PersonView(MasterView): | |||
|         """ | ||||
|         View which allows a person's "preferred" phone to be set. | ||||
|         """ | ||||
|         model = self.model | ||||
|         person = self.get_instance() | ||||
|         data = dict(self.request.json_body) | ||||
| 
 | ||||
|  | @ -1016,6 +1047,7 @@ class PersonView(MasterView): | |||
|         """ | ||||
|         View which updates an email address for the person. | ||||
|         """ | ||||
|         model = self.model | ||||
|         person = self.get_instance() | ||||
|         data = dict(self.request.json_body) | ||||
| 
 | ||||
|  | @ -1039,6 +1071,7 @@ class PersonView(MasterView): | |||
|         """ | ||||
|         View which allows a person's email address to be deleted. | ||||
|         """ | ||||
|         model = self.model | ||||
|         person = self.get_instance() | ||||
|         data = dict(self.request.json_body) | ||||
| 
 | ||||
|  | @ -1059,6 +1092,7 @@ class PersonView(MasterView): | |||
|         """ | ||||
|         View which allows a person's "preferred" email to be set. | ||||
|         """ | ||||
|         model = self.model | ||||
|         person = self.get_instance() | ||||
|         data = dict(self.request.json_body) | ||||
| 
 | ||||
|  | @ -1192,6 +1226,7 @@ class PersonView(MasterView): | |||
|         """ | ||||
|         AJAX view for updating an employee history record. | ||||
|         """ | ||||
|         model = self.model | ||||
|         person = self.get_instance() | ||||
|         employee = person.employee | ||||
| 
 | ||||
|  | @ -1459,6 +1494,7 @@ class PersonView(MasterView): | |||
|         return self.profile_changed_response(person) | ||||
| 
 | ||||
|     def create_note(self, person, form): | ||||
|         model = self.model | ||||
|         note = model.PersonNote() | ||||
|         note.type = form.validated['note_type'] | ||||
|         note.subject = form.validated['note_subject'] | ||||
|  | @ -1478,6 +1514,7 @@ class PersonView(MasterView): | |||
|         return self.profile_changed_response(person) | ||||
| 
 | ||||
|     def update_note(self, person, form): | ||||
|         model = self.model | ||||
|         note = self.Session.get(model.PersonNote, form.validated['uuid']) | ||||
|         note.subject = form.validated['note_subject'] | ||||
|         note.text = form.validated['note_text'] | ||||
|  | @ -1494,10 +1531,12 @@ class PersonView(MasterView): | |||
|         return self.profile_changed_response(person) | ||||
| 
 | ||||
|     def delete_note(self, person, form): | ||||
|         model = self.model | ||||
|         note = self.Session.get(model.PersonNote, form.validated['uuid']) | ||||
|         self.Session.delete(note) | ||||
| 
 | ||||
|     def make_user(self): | ||||
|         model = self.model | ||||
|         uuid = self.request.POST['person_uuid'] | ||||
|         person = self.Session.get(model.Person, uuid) | ||||
|         if not person: | ||||
|  | @ -1815,7 +1854,7 @@ class PersonNoteView(MasterView): | |||
|     """ | ||||
|     Master view for the PersonNote class. | ||||
|     """ | ||||
|     model_class = model.PersonNote | ||||
|     model_class = PersonNote | ||||
|     route_prefix = 'person_notes' | ||||
|     url_prefix = '/people/notes' | ||||
|     has_versions = True | ||||
|  | @ -1842,6 +1881,7 @@ class PersonNoteView(MasterView): | |||
| 
 | ||||
|     def configure_grid(self, g): | ||||
|         super().configure_grid(g) | ||||
|         model = self.model | ||||
| 
 | ||||
|         # person | ||||
|         g.set_joiner('person', lambda q: q.join(model.Person, | ||||
|  | @ -1881,7 +1921,7 @@ def valid_note_uuid(node, kw): | |||
|     session = kw['session'] | ||||
|     person_uuid = kw['person_uuid'] | ||||
|     def validate(node, value): | ||||
|         note = session.get(model.PersonNote, value) | ||||
|         note = session.get(PersonNote, value) | ||||
|         if not note: | ||||
|             raise colander.Invalid(node, "Note not found") | ||||
|         if note.person.uuid != person_uuid: | ||||
|  | @ -1906,7 +1946,7 @@ class MergePeopleRequestView(MasterView): | |||
|     """ | ||||
|     Master view for the MergePeopleRequest class. | ||||
|     """ | ||||
|     model_class = model.MergePeopleRequest | ||||
|     model_class = MergePeopleRequest | ||||
|     route_prefix = 'people_merge_requests' | ||||
|     url_prefix = '/people/merge-requests' | ||||
|     creatable = False | ||||
|  | @ -1950,8 +1990,9 @@ class MergePeopleRequestView(MasterView): | |||
|         g.set_link('keeping_uuid') | ||||
| 
 | ||||
|     def render_referenced_person_name(self, merge_request, field): | ||||
|         model = self.model | ||||
|         uuid = getattr(merge_request, field) | ||||
|         person = self.Session.get(self.model.Person, uuid) | ||||
|         person = self.Session.get(model.Person, uuid) | ||||
|         if person: | ||||
|             return str(person) | ||||
|         return "(person not found)" | ||||
|  | @ -1971,8 +2012,9 @@ class MergePeopleRequestView(MasterView): | |||
|         f.set_renderer('keeping_uuid', self.render_referenced_person) | ||||
| 
 | ||||
|     def render_referenced_person(self, merge_request, field): | ||||
|         model = self.model | ||||
|         uuid = getattr(merge_request, field) | ||||
|         person = self.Session.get(self.model.Person, uuid) | ||||
|         person = self.Session.get(model.Person, uuid) | ||||
|         if person: | ||||
|             text = str(person) | ||||
|             url = self.request.route_url('people.view', uuid=person.uuid) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Lance Edgar
						Lance Edgar