Changeset - ff01525aa7ae
[Not reviewed]
0 6 0
Lance Edgar (lance) - 17 months ago 2023-05-18 23:23:56
lance@edbob.org
Add `get_person()`, `get_customer()` etc. to AppHandler

make it delegate to appropriate handler for each method. also the
various handler methods with actual logic, are a bit more generic in
what they accept
6 files changed with 116 insertions and 27 deletions:
0 comments (0 inline, 0 general)
rattail/app.py
Show inline comments
 
@@ -1154,12 +1154,48 @@ class AppHandler(object):
 
        """
 
        Create and return a generic object.  All kwargs will be
 
        assigned as attributes to the object.
 
        """
 
        return Object(**kwargs)
 

	
 
    def get_person(self, obj, **kwargs):
 
        """
 
        Convenience method to locate a Person record for the given
 
        object.  This delegates to the
 
        :class:`~rattail.people.PeopleHandler` for actual lookup
 
        logic.
 
        """
 
        return self.get_people_handler().get_person(obj, **kwargs)
 

	
 
    def get_customer(self, obj, **kwargs):
 
        """
 
        Convenience method to locate a Customer record for the given
 
        object.  This delegates to the
 
        :class:`~rattail.clientele.ClienteleHandler` for actual lookup
 
        logic.
 
        """
 
        return self.get_clientele_handler().get_customer(obj, **kwargs)
 

	
 
    def get_employee(self, obj, **kwargs):
 
        """
 
        Convenience method to locate an Employee record for the given
 
        object.  This delegates to the
 
        :class:`~rattail.employment.EmploymentHandler` for actual
 
        lookup logic.
 
        """
 
        return self.get_employment_handler().get_employee(obj, **kwargs)
 

	
 
    def get_member(self, obj, **kwargs):
 
        """
 
        Convenience method to locate a Member record for the given
 
        object.  This delegates to the
 
        :class:`~rattail.membershipo.MembershipHandler` for actual
 
        lookup logic.
 
        """
 
        return self.get_membership_handler().get_member(obj, **kwargs)
 

	
 
    def get_session(self, obj):
 
        """
 
        Returns the SQLAlchemy session with which the given object is
 
        associated.  Simple convenience wrapper around
 
        :func:`sqlalchemy:sqlalchemy.orm.object_session()`.
 
        """
rattail/batch/custorder.py
Show inline comments
 
@@ -171,13 +171,13 @@ class CustomerOrderBatchHandler(BatchHandler):
 
        """
 
        clientele = self.app.get_clientele_handler()
 
        customer_required = self.new_order_requires_customer()
 

	
 
        # nb. person is always required
 
        if customer and not person:
 
            person = clientele.get_person(customer)
 
            person = self.app.get_person(customer)
 
        if not person:
 
            raise ValueError("Must specify a person")
 

	
 
        # customer may or may not be optional
 
        if person and not customer:
 
            customer = clientele.get_customer(person)
rattail/clientele.py
Show inline comments
 
# -*- coding: utf-8; -*-
 
################################################################################
 
#
 
#  Rattail -- Retail Software Framework
 
#  Copyright © 2010-2022 Lance Edgar
 
#  Copyright © 2010-2023 Lance Edgar
 
#
 
#  This file is part of Rattail.
 
#
 
#  Rattail is free software: you can redistribute it and/or modify it under the
 
#  terms of the GNU General Public License as published by the Free Software
 
#  Foundation, either version 3 of the License, or (at your option) any later
 
@@ -21,13 +21,13 @@
 
#
 
################################################################################
 
"""
 
Clientele Handler
 
"""
 

	
 
from __future__ import unicode_literals, absolute_import
 
import warnings
 

	
 
from rattail.util import load_object
 
from rattail.app import GenericHandler
 

	
 

	
 
class ClienteleHandler(GenericHandler):
 
@@ -62,23 +62,34 @@ class ClienteleHandler(GenericHandler):
 
        customer = self.make_customer(person)
 
        session.add(customer)
 
        session.flush()
 
        session.refresh(person)
 
        return customer
 

	
 
    def get_customer(self, person):
 
    def get_customer(self, obj):
 
        """
 
        Returns the customer associated with the given person, if there is one.
 
        Return the Customer associated with the given object, if any.
 
        """
 
        return person.only_customer(require=False)
 
        model = self.model
 

	
 
        if isinstance(obj, model.Customer):
 
            return obj
 

	
 
        if isinstance(obj, model.Person):
 
            customer = person.only_customer(require=False)
 
            if customer:
 
                return customer
 

	
 
    def get_person(self, customer):
 
        """
 
        Returns the person associated with the given customer, if there is one.
 
        """
 
        return customer.only_person(require=False)
 
        warnings.warn("ClienteleHandler.get_person() is deprecated; "
 
                      "please use AppHandler.get_person() instead")
 

	
 
        return self.app.get_person(member)
 

	
 
    def make_customer(self, person, **kwargs):
 
        """
 
        Create and return a new customer record.
 
        """
 
        customer = self.model.Customer()
 
@@ -92,13 +103,13 @@ class ClienteleHandler(GenericHandler):
 
        customer, or its first person.
 
        """
 
        phone = customer.first_phone()
 
        if phone:
 
            return phone
 

	
 
        person = self.get_person(customer)
 
        person = self.app.get_person(customer)
 
        if person:
 
            return person.first_phone()
 

	
 
    def get_first_phone_number(self, customer, **kwargs):
 
        """
 
        Return the first available phone number found, either for the
 
@@ -114,13 +125,13 @@ class ClienteleHandler(GenericHandler):
 
        customer, or its first person.
 
        """
 
        email = customer.first_email(invalid=invalid)
 
        if email:
 
            return email
 

	
 
        person = self.get_person(customer)
 
        person = self.app.get_person(customer)
 
        if person:
 
            return person.first_email(invalid=invalid)
 

	
 
    def get_first_email_address(self, customer, invalid=False, **kwargs):
 
        """
 
        Return the first available email address found, either for the
rattail/employment.py
Show inline comments
 
# -*- coding: utf-8; -*-
 
################################################################################
 
#
 
#  Rattail -- Retail Software Framework
 
#  Copyright © 2010-2022 Lance Edgar
 
#  Copyright © 2010-2023 Lance Edgar
 
#
 
#  This file is part of Rattail.
 
#
 
#  Rattail is free software: you can redistribute it and/or modify it under the
 
#  terms of the GNU General Public License as published by the Free Software
 
#  Foundation, either version 3 of the License, or (at your option) any later
 
@@ -21,16 +21,12 @@
 
#
 
################################################################################
 
"""
 
Employment Handler
 
"""
 

	
 
from __future__ import unicode_literals, absolute_import
 

	
 
import six
 

	
 
from rattail.util import load_object
 
from rattail.app import GenericHandler
 

	
 

	
 
class EmploymentHandler(GenericHandler):
 
    """
 
@@ -103,17 +99,25 @@ class EmploymentHandler(GenericHandler):
 

	
 
        session = self.get_session(person)
 
        employee = self.make_employee(person)
 
        session.flush()
 
        return employee
 

	
 
    def get_employee(self, person):
 
    def get_employee(self, obj):
 
        """
 
        Returns the employee associated with the given person, if there is one.
 
        Returns the Employee associated with the given object, if any.
 
        """
 
        return person.employee
 
        model = self.model
 

	
 
        if isinstance(obj, model.Employee):
 
            return obj
 

	
 
        if isinstance(obj, model.Person):
 
            emplyoyee = person.employee
 
            if employee:
 
                return employee
 

	
 
    def make_employee(self, person):
 
        """
 
        Create and return a new employee record.
 
        """
 
        employee = self.model.Employee()
 
@@ -164,14 +168,14 @@ class EmploymentHandler(GenericHandler):
 
        return {
 
            'uuid': employee.uuid,
 
            'id': employee.id,
 
            'status': employee.status,
 
            'status_display': status_display,
 
            'current': employee.status == self.enum.EMPLOYEE_STATUS_CURRENT,
 
            'start_date': six.text_type(history.start_date) if history else None,
 
            'end_date': six.text_type(history.end_date) if history and history.end_date else None,
 
            'start_date': str(history.start_date) if history else None,
 
            'end_date': str(history.end_date) if history and history.end_date else None,
 
        }
 

	
 

	
 
def get_employment_handler(config, **kwargs):
 
    """
 
    Create and return the configured :class:`EmploymentHandler` instance.
rattail/membership.py
Show inline comments
 
# -*- coding: utf-8; -*-
 
################################################################################
 
#
 
#  Rattail -- Retail Software Framework
 
#  Copyright © 2010-2022 Lance Edgar
 
#  Copyright © 2010-2023 Lance Edgar
 
#
 
#  This file is part of Rattail.
 
#
 
#  Rattail is free software: you can redistribute it and/or modify it under the
 
#  terms of the GNU General Public License as published by the Free Software
 
#  Foundation, either version 3 of the License, or (at your option) any later
 
@@ -21,13 +21,13 @@
 
#
 
################################################################################
 
"""
 
Membership Handler
 
"""
 

	
 
from __future__ import unicode_literals, absolute_import
 
import warnings
 

	
 
from rattail.util import load_object
 
from rattail.app import GenericHandler
 

	
 

	
 
class MembershipHandler(GenericHandler):
 
@@ -51,29 +51,36 @@ class MembershipHandler(GenericHandler):
 
    def begin_membership(self, member, **kwargs):
 
        """
 
        Begin an active membership.
 
        """
 
        raise NotImplementedError
 

	
 
    def get_member(self, person):
 
    def get_member(self, obj):
 
        """
 
        Returns the member associated with the given person, if there is one.
 
        """
 
        raise NotImplementedError
 
        model = self.model
 

	
 
        if isinstance(obj, model.Member):
 
            return obj
 

	
 
        person = self.app.get_person(obj)
 
        if person and person.members:
 
            return person.members[0]
 

	
 
    def get_customer(self, member):
 
        """
 
        Returns the customer associated with the given member, if there is one.
 
        """
 
        raise NotImplementedError
 

	
 
    def get_person(self, member):
 
        """
 
        Returns the person associated with the given member, if there is one.
 
        """
 
        clientele = self.app.get_clientele_handler()
 
        customer = self.get_customer(member)
 
        person = clientele.get_person(customer)
 
        return person
 
        warnings.warn("MembershipHandler.get_person() is deprecated; "
 
                      "please use AppHandler.get_person() instead")
 

	
 
        return self.app.get_person(member)
 

	
 
    def get_last_patronage_date(self, member, **kwargs):
 
        raise NotImplementedError
rattail/people.py
Show inline comments
 
@@ -36,12 +36,43 @@ from rattail.time import make_utc
 

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

	
 
    def get_person(self, obj, **kwargs):
 
        """
 
        Retrieve the Person related to the given object.
 

	
 
        This is a rather fundamental method, in that it is called by
 
        several other methods, both within this handler as well as
 
        others.  There is even a shortcut to it, accessible via
 
        :meth:`rattail.app.AppHandler.get_person()`.
 

	
 
        Its purpose is to navigate relationships as needed, to get at
 
        the "default" person associated with the object.  Depending on
 
        how the app tracks relationships, this logic may need to vary.
 
        """
 
        model = self.model
 

	
 
        if isinstance(obj, model.Person):
 
            return obj
 

	
 
        if isinstance(obj, model.User):
 
            if obj.person:
 
                return obj.person
 

	
 
        if isinstance(obj, model.Customer):
 
            person = obj.only_person(require=False)
 
            if person:
 
                return person
 

	
 
        if isinstance(obj, model.Member):
 
            if obj.person:
 
                return obj.person
 

	
 
    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.
0 comments (0 inline, 0 general)