Changeset - 53e969217085
[Not reviewed]
0 3 2
Lance Edgar (lance) - 3 years ago 2021-08-18 19:30:36
lance@edbob.org
Add merge-related methods to `PeopleHandler`, plus some docs

also deprecate `get_people_handler()` function
5 files changed with 113 insertions and 9 deletions:
0 comments (0 inline, 0 general)
docs/api/index.rst
Show inline comments
 
@@ -23,12 +23,13 @@ attributes and method signatures etc.
 
   rattail/db/model
 
   rattail/db/model.batch
 
   rattail/db/model.batch.labels
 
   rattail/db/model.batch.purchase
 
   rattail/db/model.batch.vendorcatalog
 
   rattail/db/model.datasync
 
   rattail/db/model.people
 
   rattail/db/model.products
 
   rattail/db/model.purchase
 
   rattail/db/util
 
   rattail/enum
 
   rattail/exceptions
 
   rattail/filemon/index
 
@@ -46,9 +47,10 @@ attributes and method signatures etc.
 
   rattail/importing/rattail
 
   rattail/importing/sqlalchemy
 
   rattail/reporting/index
 
   rattail/reporting/handlers
 
   rattail/logging
 
   rattail/mail
 
   rattail/people
 
   rattail/time
 
   rattail/upgrades
 
   rattail/win32
docs/api/rattail/db/model.people.rst
Show inline comments
 
new file 100644
 

	
 
``rattail.db.model.people``
 
===========================
 

	
 
.. automodule:: rattail.db.model.people
 
  :members:
docs/api/rattail/people.rst
Show inline comments
 
new file 100644
 

	
 
``rattail.people``
 
==================
 

	
 
.. automodule:: rattail.people
 
   :members:
rattail/app.py
Show inline comments
 
@@ -76,15 +76,22 @@ class AppHandler(object):
 
        if not hasattr(self, 'mail_handler'):
 
            from rattail.mail import get_email_handler
 
            self.mail_handler = get_email_handler(self.config, **kwargs)
 
        return self.mail_handler
 

	
 
    def get_people_handler(self, **kwargs):
 
        """
 
        Returns a reference to the configured People Handler.
 

	
 
        See also :doc:`rattail-manual:base/handlers/other/people`.
 
        """
 
        if not hasattr(self, 'people_handler'):
 
            from rattail.people import get_people_handler
 
            self.people_handler = get_people_handler(self.config, **kwargs)
 
            spec = self.config.get('rattail', 'people.handler',
 
                                   default='rattail.people:PeopleHandler')
 
            factory = load_object(spec)
 
            self.people_handler = factory(self.config, **kwargs)
 
        return self.people_handler
 

	
 
    def get_products_handler(self, **kwargs):
 
        if not hasattr(self, 'products_handler'):
 
            from rattail.products import get_products_handler
 
            self.products_handler = get_products_handler(self.config, **kwargs)
rattail/people.py
Show inline comments
 
@@ -19,26 +19,39 @@
 
#  You should have received a copy of the GNU General Public License along with
 
#  Rattail.  If not, see <http://www.gnu.org/licenses/>.
 
#
 
################################################################################
 
"""
 
People Handler
 

	
 
See also :doc:`rattail-manual:base/handlers/other/people`.
 
"""
 

	
 
from __future__ import unicode_literals, absolute_import
 

	
 
from rattail.util import load_object
 
import warnings
 

	
 
from sqlalchemy import orm
 

	
 
from rattail.app import GenericHandler
 

	
 

	
 
class PeopleHandler(GenericHandler):
 
    """
 
    Base class and default implementation for people handlers.
 
    """
 

	
 
    def normalize_full_name(self, first, last, **kwargs):
 
        """
 
        Normalize a "full" name based on the given first and last
 
        names.  Tries to be smart about collapsing whitespace etc.
 

	
 
        :param first: First name.
 
        :param last: Last name.
 
        :returns: First and last name combined.
 
        """
 
        from rattail.db.util import normalize_full_name
 
        return normalize_full_name(first, last)
 

	
 
    def update_names(self, person, **kwargs):
 
        """
 
        Update name(s) for the given person.
 
@@ -77,17 +90,87 @@ class PeopleHandler(GenericHandler):
 
        if not address:
 
            address = person.add_address(**kwargs)
 
            # TODO: this might be a good idea..maybe if a kwarg flag is set?
 
            # person.set_primary_address(address)
 
        return address
 

	
 
    def get_merge_preview_fields(self, **kwargs):
 
        """
 
        Returns a sequence of fields which will be used during a merge
 
        preview.
 
        """
 
        def F(name, **kwargs):
 
            field = {'name': name}
 
            field.update(kwargs)
 
            return field
 

	
 
        return [
 
            F('uuid'),
 
            F('first_name'),
 
            F('last_name'),
 
            F('display_name'),
 
            F('usernames', additive=True),
 
            F('member_uuids', additive=True),
 
        ]
 

	
 
    def get_merge_preview_data(self, person, **kwargs):
 
        """
 
        Must return a data dictionary for the given person, which can
 
        be presented to the user during a merge preview.
 
        """
 
        return {
 
            'uuid': person.uuid,
 
            'first_name': person.first_name,
 
            'last_name': person.last_name,
 
            'display_name': person.display_name,
 
            'usernames': [u.username for u in person.users],
 
            'member_uuids': [m.uuid for m in person.members],
 
        }
 

	
 
    def why_not_merge(self, removing, keeping, **kwargs):
 
        """
 
        Evaluate the given merge candidates and if there is a reason *not*
 
        to merge them, return that reason.
 

	
 
        :param removing: Person record which will be removed, should the
 
           merge happen.
 
        :param keeping: Person record which will be kept, should the
 
           merge happen.
 
        :returns: String indicating reason not to merge, or ``None``.
 
        """
 

	
 
    def perform_merge(self, removing, keeping, **kwargs):
 
        """
 
        Perform an actual merge of the 2 given people.
 

	
 
        :param removing: Person record which should be removed.
 
        :param keeping: Person record which should be kept.
 
        """
 
        # move Member records to final Person
 
        for member in list(removing.members):
 
            removing.members.remove(member)
 
            keeping.members.append(member)
 

	
 
        # move User records to final Person
 
        for user in list(removing.users):
 
            removing.users.remove(user)
 
            keeping.users.append(user)
 

	
 
        # delete unwanted Person
 
        session = orm.object_session(keeping)
 
        session.delete(removing)
 
        session.flush()
 

	
 

	
 
def get_people_handler(config, **kwargs):
 
    """
 
    Create and return the configured :class:`PeopleHandler` instance.
 

	
 
    .. warning::
 
       This function is deprecated; please use
 
       :meth:`~rattail.app.AppHandler.get_people_handler` instead.
 
    """
 
    spec = config.get('rattail', 'people.handler')
 
    if spec:
 
        factory = load_object(spec)
 
    else:
 
        factory = PeopleHandler
 
    return factory(config, **kwargs)
 
    warnings.warn("get_people_handler() function is deprecated, "
 
                  "please use app.get_people_handler() method instead",
 
                  DeprecationWarning)
 
    app = config.get_app()
 
    return app.get_people_handler(**kwargs)
0 comments (0 inline, 0 general)