Add basic CRUD for Person "preferred first name"
only shown if config flag says so
This commit is contained in:
parent
cdc857065b
commit
1889f7d269
|
@ -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…
Reference in a new issue