Coverage for .tox/coverage/lib/python3.11/site-packages/wuttaweb/views/people.py: 100%

66 statements  

« prev     ^ index     » next       coverage.py v7.6.1, created at 2024-08-23 22:41 -0500

1# -*- coding: utf-8; -*- 

2################################################################################ 

3# 

4# wuttaweb -- Web App for Wutta Framework 

5# Copyright © 2024 Lance Edgar 

6# 

7# This file is part of Wutta Framework. 

8# 

9# Wutta Framework is free software: you can redistribute it and/or modify it 

10# under the terms of the GNU General Public License as published by the Free 

11# Software Foundation, either version 3 of the License, or (at your option) any 

12# later version. 

13# 

14# Wutta Framework is distributed in the hope that it will be useful, but 

15# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 

16# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 

17# more details. 

18# 

19# You should have received a copy of the GNU General Public License along with 

20# Wutta Framework. If not, see <http://www.gnu.org/licenses/>. 

21# 

22################################################################################ 

23""" 

24Views for people 

25""" 

26 

27import sqlalchemy as sa 

28 

29from wuttjamaican.db.model import Person 

30from wuttaweb.views import MasterView 

31from wuttaweb.forms.schema import UserRefs 

32 

33 

34class PersonView(MasterView): 

35 """ 

36 Master view for people. 

37 

38 Default route prefix is ``people``. 

39 

40 Notable URLs provided by this class: 

41 

42 * ``/people/`` 

43 * ``/people/new`` 

44 * ``/people/XXX`` 

45 * ``/people/XXX/edit`` 

46 * ``/people/XXX/delete`` 

47 """ 

48 model_class = Person 

49 model_title_plural = "People" 

50 route_prefix = 'people' 

51 sort_defaults = 'full_name' 

52 has_autocomplete = True 

53 

54 grid_columns = [ 

55 'full_name', 

56 'first_name', 

57 'middle_name', 

58 'last_name', 

59 ] 

60 

61 filter_defaults = { 

62 'full_name': {'active': True}, 

63 } 

64 

65 def configure_grid(self, g): 

66 """ """ 

67 super().configure_grid(g) 

68 

69 # full_name 

70 g.set_link('full_name') 

71 

72 # first_name 

73 g.set_link('first_name') 

74 

75 # last_name 

76 g.set_link('last_name') 

77 

78 def configure_form(self, f): 

79 """ """ 

80 super().configure_form(f) 

81 person = f.model_instance 

82 

83 # TODO: master should handle these? (nullable column) 

84 f.set_required('first_name', False) 

85 f.set_required('middle_name', False) 

86 f.set_required('last_name', False) 

87 

88 # users 

89 # nb. colanderalchemy wants to do some magic for the true 

90 # 'users' relationship, so we use a different field name 

91 f.remove('users') 

92 if not (self.creating or self.editing): 

93 f.append('_users') 

94 f.set_readonly('_users') 

95 f.set_node('_users', UserRefs(self.request)) 

96 f.set_default('_users', [u.uuid for u in person.users]) 

97 

98 def autocomplete_query(self, term): 

99 """ """ 

100 model = self.app.model 

101 session = self.Session() 

102 query = session.query(model.Person) 

103 criteria = [model.Person.full_name.ilike(f'%{word}%') 

104 for word in term.split()] 

105 query = query.filter(sa.and_(*criteria))\ 

106 .order_by(model.Person.full_name) 

107 return query 

108 

109 def view_profile(self, session=None): 

110 """ """ 

111 person = self.get_instance(session=session) 

112 context = { 

113 'person': person, 

114 'instance': person, 

115 } 

116 return self.render_to_response('view_profile', context) 

117 

118 def make_user(self): 

119 """ """ 

120 self.request.session.flash("TODO: this feature is not yet supported", 'error') 

121 return self.redirect(self.request.get_referrer()) 

122 

123 @classmethod 

124 def defaults(cls, config): 

125 """ """ 

126 

127 # nb. Person may come from custom model 

128 wutta_config = config.registry.settings['wutta_config'] 

129 app = wutta_config.get_app() 

130 cls.model_class = app.model.Person 

131 

132 cls._defaults(config) 

133 cls._people_defaults(config) 

134 

135 @classmethod 

136 def _people_defaults(cls, config): 

137 route_prefix = cls.get_route_prefix() 

138 url_prefix = cls.get_url_prefix() 

139 instance_url_prefix = cls.get_instance_url_prefix() 

140 permission_prefix = cls.get_permission_prefix() 

141 

142 # view profile 

143 config.add_route(f'{route_prefix}.view_profile', 

144 f'{instance_url_prefix}/profile', 

145 request_method='GET') 

146 config.add_view(cls, attr='view_profile', 

147 route_name=f'{route_prefix}.view_profile', 

148 permission=f'{permission_prefix}.view_profile') 

149 

150 # make user for person 

151 config.add_route(f'{route_prefix}.make_user', 

152 f'{url_prefix}/make-user', 

153 request_method='POST') 

154 config.add_view(cls, attr='make_user', 

155 route_name=f'{route_prefix}.make_user', 

156 permission='users.create') 

157 

158 

159def defaults(config, **kwargs): 

160 base = globals() 

161 

162 PersonView = kwargs.get('PersonView', base['PersonView']) 

163 PersonView.defaults(config) 

164 

165 

166def includeme(config): 

167 defaults(config)