Blame view

app/models.py 8.91 KB
76ef4fbe   hitier   Click, Sqlalchemy...
1
from flask_sqlalchemy import SQLAlchemy
454728d5   hitier   Use sqlalchemy re...
2
from sqlalchemy.orm import relationship
76ef4fbe   hitier   Click, Sqlalchemy...
3
4
5
6

db = SQLAlchemy()


a2074730   hitier   Feed projects labels
7
#
142e2e9d   hitier   New Formable clas...
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#
#

class Formable:
    """
    Parent class allowing some html form  facilities

    """
    export_keys = []

    def from_request(self, form_request):
        """
        Get a form request structure and fill in our fields

        :param form_request:
        :return:
        """
        for key in self.export_keys:
            setattr(self, key, form_request.form.get(key))

    def to_struct(self):
        """
        Export the orm object to a structure easily used in jinja

        :return:  nothing
        """
e20cd5d4   hitier   Now import/export...
34
        _struct = {'id': self.id}
142e2e9d   hitier   New Formable clas...
35
36
37
38
39
40
41
        for key in self.export_keys:
            _value = getattr(self, key)
            _struct[key] = '' if _value is None else _value
        return _struct


#
a2074730   hitier   Feed projects labels
42
43
# Categorized projects
#
a53e2fff   hitier   New category/labe...
44
45
46
47
48
49
50
51
52
53
# There is one label list,
# each label belongs to one or more categories.
#
# The projects are labelled by one or more label.
#
# Thus this is modeled with classes
#    Project, Label and Category
# And many_to_many association are done through
#    ProjectLabel and CategoryLabel
#
a2074730   hitier   Feed projects labels
54

a53e2fff   hitier   New category/labe...
55
class Project(db.Model, Formable):
a2074730   hitier   Feed projects labels
56
57
58
59
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String)
    labels = relationship("ProjectLabel", back_populates="project")

3c53ad45   hitier   Project edit work...
60
    # add keys to import/export
a53e2fff   hitier   New category/labe...
61
    export_keys = ['name']
a2074730   hitier   Feed projects labels
62

3c53ad45   hitier   Project edit work...
63
64
65
66
67
68
69
    def from_request(self, form_request):
        """
        overide parent method to deal with category labels

        :param form_request:
        :return:
        """
85ee3eec   hitier   Completed Label e...
70
        super(Project, self).from_request(form_request)
3c53ad45   hitier   Project edit work...
71
72
73
74
75
76
77
78
79
        self.labels.clear()
        form_labels = []
        for _c in Category.query.all():
            form_labels = form_labels + form_request.form.getlist(_c.name)
        for label_id in form_labels:
            n_l = Label.query.get(int(label_id))
            n_pl = ProjectLabel(project=self, label=n_l)
            self.labels.append(n_pl)

a53e2fff   hitier   New category/labe...
80
81
82
83
    def to_struct(self):
        """
        overide parent method to include one key: agent.fullname

3c53ad45   hitier   Project edit work...
84
85
        Mainly we add the 'labels' element containing list of label names
        and we add the 'category_labels' element containing a dict
a53e2fff   hitier   New category/labe...
86
87
88
89
        where category key contains labels for that project.
        :return:
        """
        _struct = super(Project, self).to_struct()
3c53ad45   hitier   Project edit work...
90
        _struct['labels'] = [_l.label.name for _l in self.labels]
9b43874a   hitier   Change project_st...
91
        _struct['category_labels'] = {}
a53e2fff   hitier   New category/labe...
92
93
94
95
96
        for _c in Category.query.all():
            category_labels = []
            for _l in self.labels:
                if _l.label in [_cl.label for _cl in _c.labels]:
                    category_labels.append(_l.label.name)
9b43874a   hitier   Change project_st...
97
            _struct['category_labels'][_c.name] = category_labels
a53e2fff   hitier   New category/labe...
98
99
100
101
102
103
104
105
106
        return _struct


class ProjectLabel(db.Model):
    """
    Labelling projects.
    On project can have many labels.
    And one label will be set to many projects
    """
d6b9daca   hitier   Feed categories a...
107
    id = db.Column(db.Integer, primary_key=True)
a53e2fff   hitier   New category/labe...
108
109
110
111
    project_id = db.Column(db.Integer, db.ForeignKey('project.id'))
    label_id = db.Column(db.Integer, db.ForeignKey('label.id'))
    project = relationship("Project", back_populates="labels")
    label = relationship("Label", back_populates="projects")
d6b9daca   hitier   Feed categories a...
112
113


85ee3eec   hitier   Completed Label e...
114
class Label(db.Model, Formable):
d6b9daca   hitier   Feed categories a...
115
    id = db.Column(db.Integer, primary_key=True)
a2074730   hitier   Feed projects labels
116
    name = db.Column(db.String, unique=True)
d6b9daca   hitier   Feed categories a...
117
    category_id = db.Column(db.Integer, db.ForeignKey('category.id'))
a2074730   hitier   Feed projects labels
118
    projects = relationship("ProjectLabel", back_populates="label")
a53e2fff   hitier   New category/labe...
119
    categories = relationship("CategoryLabel", back_populates="label")
a2074730   hitier   Feed projects labels
120

85ee3eec   hitier   Completed Label e...
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
    export_keys = ['name']

    def from_request(self, form_request):
        """
        overide parent method to deal with category labels

        :param form_request:
        :return:
        """
        super(Label, self).from_request(form_request)
        self.categories.clear()
        for _c_id in form_request.form.getlist("categories"):
            n_c = Category.query.get(int(_c_id))
            _cl = CategoryLabel(category=n_c, label=self)
            self.categories.append(_cl)

    def to_struct(self):
        """
        overide parent method to include one key: categories

        Mainly we add the 'categories' element containing list of categories names
        :return:
        """
        _struct = super(Label, self).to_struct()
        _struct['categories'] = [_cl.category.name for _cl in self.categories]
        return _struct

a2074730   hitier   Feed projects labels
148

a53e2fff   hitier   New category/labe...
149
150
151
152
153
154
155
156
class CategoryLabel(db.Model):
    """
    Categorizing labels:
    one label can be added to many categories
    one category hosts many labels
    """
    id = db.Column(db.Integer, primary_key=True)
    category_id = db.Column(db.Integer, db.ForeignKey('category.id'))
a2074730   hitier   Feed projects labels
157
    label_id = db.Column(db.Integer, db.ForeignKey('label.id'))
a53e2fff   hitier   New category/labe...
158
159
    category = relationship("Category", back_populates="labels")
    label = relationship("Label", back_populates="categories")
a2074730   hitier   Feed projects labels
160

a53e2fff   hitier   New category/labe...
161

fc06cbe5   hitier   Category edit for...
162
class Category(db.Model, Formable):
a53e2fff   hitier   New category/labe...
163
164
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String)
a53e2fff   hitier   New category/labe...
165
    labels = relationship("CategoryLabel", back_populates="category")
a2074730   hitier   Feed projects labels
166

fc06cbe5   hitier   Category edit for...
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
    export_keys = ['name']

    def from_request(self, form_request):
        """
        overide parent method to deal with category labels

        :param form_request:
        :return:
        """
        super(Category, self).from_request(form_request)
        self.labels.clear()
        for _l_id in form_request.form.getlist("labels"):
            n_c = Label.query.get(int(_l_id))
            _cl = CategoryLabel(label=n_c, category=self)
            self.labels.append(_cl)

    def to_struct(self):
        """
        overide parent method to include one key: labels

        Mainly we add the 'labels' element containing list of labels names
        :return:
        """
        _struct = super(Category, self).to_struct()
        _struct['labels'] = [_cl.label.name for _cl in self.labels]
        return _struct

d6b9daca   hitier   Feed categories a...
194

a2074730   hitier   Feed projects labels
195
196
197
#
# Agents
#
d6b9daca   hitier   Feed categories a...
198

ad3a824d   hitier   Add more agent fi...
199
200
201
class AgentBap(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(16))
f3dbebc2   hitier   New agent relatio...
202
    agents = relationship("Agent", back_populates="bap")
ad3a824d   hitier   Add more agent fi...
203
204
205
206
207


class AgentGrade(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(16))
f3dbebc2   hitier   New agent relatio...
208
    agents = relationship("Agent", back_populates="grade")
ad3a824d   hitier   Add more agent fi...
209
210
211
212
213


class AgentStatus(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(16))
f3dbebc2   hitier   New agent relatio...
214
    agents = relationship("Agent", back_populates="status")
ad3a824d   hitier   Add more agent fi...
215
216
217
218
219


class Company(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(16))
f3dbebc2   hitier   New agent relatio...
220
    agents = relationship("Agent", back_populates="company")
ad3a824d   hitier   Add more agent fi...
221
222


142e2e9d   hitier   New Formable clas...
223
class Agent(db.Model, Formable):
2784d9cc   hitier   Add models for ch...
224
225
226
    id = db.Column(db.Integer, primary_key=True)
    firstname = db.Column(db.String(100))
    secondname = db.Column(db.String(100))
f3dbebc2   hitier   New agent relatio...
227
228
    virtual = db.Column(db.Integer)  # integer boolean
    permanent = db.Column(db.Integer)  # integer boolean
ad3a824d   hitier   Add more agent fi...
229
230
231
232
    company_id = db.Column(db.Integer, db.ForeignKey('company.id'))
    grade_id = db.Column(db.Integer, db.ForeignKey('agent_grade.id'))
    status_id = db.Column(db.Integer, db.ForeignKey('agent_status.id'))
    bap_id = db.Column(db.Integer, db.ForeignKey('agent_bap.id'))
f3dbebc2   hitier   New agent relatio...
233
234
235
236
    grade = relationship("AgentGrade", back_populates="agents")
    bap = relationship("AgentBap", back_populates="agents")
    status = relationship("AgentStatus", back_populates="agents")
    company = relationship("Company", back_populates="agents")
2784d9cc   hitier   Add models for ch...
237

ca0797d6   hitier   New agent edit form
238
    @property
ca0797d6   hitier   New agent edit form
239
240
241
    def fullname(self):
        return f"{self.secondname} {self.firstname}"

bb0ea5a5   hitier   New charge add form
242
243
244
245
    @property
    def namefull(self):
        return f"{self.firstname} {self.secondname}"

142e2e9d   hitier   New Formable clas...
246
247
248
    # has to be set as we inherit Formable
    #
    export_keys = ['firstname', 'secondname', 'virtual', 'permanent', 'company_id', 'status_id', 'grade_id', 'bap_id']
ca0797d6   hitier   New agent edit form
249

142e2e9d   hitier   New Formable clas...
250
    def to_struct(self):
ca0797d6   hitier   New agent edit form
251
        """
142e2e9d   hitier   New Formable clas...
252
        overide parent method to include one key: agent.fullname
ca0797d6   hitier   New agent edit form
253
254
        :return:
        """
142e2e9d   hitier   New Formable clas...
255
256
        _struct = super(Agent, self).to_struct()
        _struct['fullname'] = self.fullname
142e2e9d   hitier   New Formable clas...
257
        return _struct
ca0797d6   hitier   New agent edit form
258

2784d9cc   hitier   Add models for ch...
259

2784d9cc   hitier   Add models for ch...
260
261
262
class Service(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), unique=True)
1002c994   hitier   Also feed ids fro...
263
    abbr = db.Column(db.String(50), unique=True)
2784d9cc   hitier   Add models for ch...
264
265


2784d9cc   hitier   Add models for ch...
266
267
268
269
270
271
272
273
274
275
276
class Capacity(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), unique=True)


class Period(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), unique=True)
    num_months = db.Column(db.Integer)


142e2e9d   hitier   New Formable clas...
277
class Charge(db.Model, Formable):
2784d9cc   hitier   Add models for ch...
278
279
280
281
    id = db.Column(db.Integer, primary_key=True)
    agent_id = db.Column(db.Integer, db.ForeignKey('agent.id'))
    project_id = db.Column(db.Integer, db.ForeignKey('project.id'))
    service_id = db.Column(db.Integer, db.ForeignKey('service.id'))
582b4b3a   hitier   Add capacity comp...
282
    capacity_id = db.Column(db.Integer, db.ForeignKey('capacity.id'))
2784d9cc   hitier   Add models for ch...
283
284
    period_id = db.Column(db.Integer, db.ForeignKey('period.id'))
    charge_rate = db.Column(db.Integer)
12de0b1d   hitier   Now charge add ro...
285

142e2e9d   hitier   New Formable clas...
286
287
288
    # Overwrite Formable default to fit our own members
    #
    export_keys = ['agent_id', 'project_id', 'service_id', 'capacity_id', 'period_id', 'charge_rate']