Add new OrgHandler class, deprecate some db.api functions

This commit is contained in:
Lance Edgar 2023-08-18 15:36:02 -05:00
parent ce8b0faf5d
commit 8c66d6f161
3 changed files with 133 additions and 27 deletions

View file

@ -974,6 +974,20 @@ class AppHandler(object):
self.membership_handler = factory(self.config, **kwargs)
return self.membership_handler
def get_org_handler(self, **kwargs):
"""
Get the configured "org" handler.
:returns: The :class:`~rattail.org.OrgHandler` instance for
the app.
"""
if not hasattr(self, 'org_handler'):
spec = self.config.get('rattail', 'org.handler',
default='rattail.org:OrgHandler')
factory = load_object(spec)
self.org_handler = factory(self.config, **kwargs)
return self.org_handler
def get_people_handler(self, **kwargs):
"""
Get the configured "people" handler.

View file

@ -24,27 +24,19 @@
API for Organizational Models
"""
import warnings
from sqlalchemy.orm.exc import NoResultFound
from rattail.db import model
# TODO: need to refactor this into the AppHandler, or..?
def get_department(session, key):
"""
Locate and return a department for the given key, if possible.
""" DEPRECATED """
warnings.warn("db.api.get_department() function is deprecated; "
"please use OrgHandler.get_department() method instead",
DeprecationWarning, stacklevel=2)
First the key is assumed to be a ``Department.number`` value. If no
matches are found, then it looks for a special setting in the database. If
one is found, ``get_department()`` is called again with its value.
:param session: Active database session.
:param key: Value to use when searching for the department.
:returns: The :class:`rattail.db.model.Department` instance if found;
otherwise ``None``.
"""
# Department.uuid match?
department = session.get(model.Department, str(key))
if department:
@ -67,20 +59,11 @@ def get_department(session, key):
# TODO: need to refactor this into the AppHandler, or..?
def get_subdepartment(session, key):
"""
Locate and return a subdepartment for the given key, if possible.
""" DEPRECATED """
warnings.warn("db.api.get_subdepartment() function is deprecated; "
"please use OrgHandler.get_subdepartment() method instead",
DeprecationWarning, stacklevel=2)
First the key is assumed to be a ``Subdepartment.number`` value. If no
matches are found, then it looks for a special setting in the database. If
one is found, ``get_subdepartment()`` is called again with its value.
:param session: Active database session.
:param key: Value to use when searching for the subdepartment.
:returns: The :class:`rattail.db.model.Subdepartment` instance if found;
otherwise ``None``.
"""
# Subdepartment.uuid match?
subdepartment = session.get(model.Subdepartment, key)
if subdepartment:

109
rattail/org.py Normal file
View file

@ -0,0 +1,109 @@
# -*- coding: utf-8; -*-
################################################################################
#
# Rattail -- Retail Software Framework
# 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
# version.
#
# Rattail is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# Rattail. If not, see <http://www.gnu.org/licenses/>.
#
################################################################################
"""
Org Handler
"""
from sqlalchemy import orm
from rattail.app import GenericHandler
class OrgHandler(GenericHandler):
"""
Base class and default implementation for org handlers.
This is meant to provide logic around the "organization" - for
instance stores and departments.
"""
def get_department(self, session, key):
"""
Locate and return a department for the given key, if possible.
First the key is assumed to be a ``Department.number`` value.
If no matches are found, then it looks for a special setting
in the database. If one is found, ``get_department()`` is
called again with its value.
:param session: Active database session.
:param key: Value to use when searching for the department.
:returns: The :class:`~rattail.db.model.Department` instance
if found; otherwise ``None``.
"""
model = self.model
# Department.uuid match?
department = session.get(model.Department, str(key))
if department:
return department
# Department.number match?
if isinstance(key, int) or key.isdigit():
try:
return session.query(model.Department).filter_by(number=key).one()
except orm.exc.NoResultFound:
pass
# try settings, if value then recurse.
key = self.app.get_setting(session, f'rattail.department.{key}')
if key is not None:
return self.get_department(session, key)
def get_subdepartment(session, key):
"""
Locate and return a subdepartment for the given key, if
possible.
First the key is assumed to be a ``Subdepartment.number``
value. If no matches are found, then it looks for a special
setting in the database. If one is found,
``get_subdepartment()`` is called again with its value.
:param session: Active database session.
:param key: Value to use when searching for the subdepartment.
:returns: The :class:`~rattail.db.model.Subdepartment`
instance if found; otherwise ``None``.
"""
model = self.model
# Subdepartment.uuid match?
subdepartment = session.get(model.Subdepartment, key)
if subdepartment:
return subdepartment
# Subdepartment.number match?
if isinstance(key, int) or key.isdigit():
try:
return session.query(model.Subdepartment).filter_by(number=key).one()
except orm.exc.NoResultFound:
pass
# try settings, if value then recurse.
key = self.app.get_setting(session, f'rattail.subdepartment.{key}')
if key is not None:
return self.get_subdepartment(session, key)