Blame view

app/models.py 7.31 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:
        """
e7b76e3e   hitier   Fix edit project ...
70
        struct = super(Project, self).from_request(form_request)
3c53ad45   hitier   Project edit work...
71
72
73
74
75
76
77
78
79
80
        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...
81
82
83
84
    def to_struct(self):
        """
        overide parent method to include one key: agent.fullname

3c53ad45   hitier   Project edit work...
85
86
        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...
87
88
89
90
        where category key contains labels for that project.
        :return:
        """
        _struct = super(Project, self).to_struct()
3c53ad45   hitier   Project edit work...
91
        _struct['labels'] = [_l.label.name for _l in self.labels]
9b43874a   hitier   Change project_st...
92
        _struct['category_labels'] = {}
a53e2fff   hitier   New category/labe...
93
94
95
96
97
        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...
98
            _struct['category_labels'][_c.name] = category_labels
a53e2fff   hitier   New category/labe...
99
100
101
102
103
104
105
106
107
        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...
108
    id = db.Column(db.Integer, primary_key=True)
a53e2fff   hitier   New category/labe...
109
110
111
112
    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...
113
114


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


a53e2fff   hitier   New category/labe...
123
124
125
126
127
128
129
130
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
131
    label_id = db.Column(db.Integer, db.ForeignKey('label.id'))
a53e2fff   hitier   New category/labe...
132
133
    category = relationship("Category", back_populates="labels")
    label = relationship("Label", back_populates="categories")
a2074730   hitier   Feed projects labels
134

a53e2fff   hitier   New category/labe...
135
136
137
138
139
140

class Category(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String)
    labels = relationship("Label", back_populates="category")
    labels = relationship("CategoryLabel", back_populates="category")
a2074730   hitier   Feed projects labels
141

d6b9daca   hitier   Feed categories a...
142

a2074730   hitier   Feed projects labels
143
144
145
#
# Agents
#
d6b9daca   hitier   Feed categories a...
146

ad3a824d   hitier   Add more agent fi...
147
148
149
class AgentBap(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(16))
f3dbebc2   hitier   New agent relatio...
150
    agents = relationship("Agent", back_populates="bap")
ad3a824d   hitier   Add more agent fi...
151
152
153
154
155


class AgentGrade(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(16))
f3dbebc2   hitier   New agent relatio...
156
    agents = relationship("Agent", back_populates="grade")
ad3a824d   hitier   Add more agent fi...
157
158
159
160
161


class AgentStatus(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(16))
f3dbebc2   hitier   New agent relatio...
162
    agents = relationship("Agent", back_populates="status")
ad3a824d   hitier   Add more agent fi...
163
164
165
166
167


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


142e2e9d   hitier   New Formable clas...
171
class Agent(db.Model, Formable):
2784d9cc   hitier   Add models for ch...
172
173
174
    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...
175
176
    virtual = db.Column(db.Integer)  # integer boolean
    permanent = db.Column(db.Integer)  # integer boolean
ad3a824d   hitier   Add more agent fi...
177
178
179
180
    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...
181
182
183
184
    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...
185

ca0797d6   hitier   New agent edit form
186
    @property
ca0797d6   hitier   New agent edit form
187
188
189
    def fullname(self):
        return f"{self.secondname} {self.firstname}"

bb0ea5a5   hitier   New charge add form
190
191
192
193
    @property
    def namefull(self):
        return f"{self.firstname} {self.secondname}"

142e2e9d   hitier   New Formable clas...
194
195
196
    # 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
197

142e2e9d   hitier   New Formable clas...
198
    def to_struct(self):
ca0797d6   hitier   New agent edit form
199
        """
142e2e9d   hitier   New Formable clas...
200
        overide parent method to include one key: agent.fullname
ca0797d6   hitier   New agent edit form
201
202
        :return:
        """
142e2e9d   hitier   New Formable clas...
203
204
        _struct = super(Agent, self).to_struct()
        _struct['fullname'] = self.fullname
142e2e9d   hitier   New Formable clas...
205
        return _struct
ca0797d6   hitier   New agent edit form
206

2784d9cc   hitier   Add models for ch...
207

2784d9cc   hitier   Add models for ch...
208
209
210
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...
211
    abbr = db.Column(db.String(50), unique=True)
2784d9cc   hitier   Add models for ch...
212
213


2784d9cc   hitier   Add models for ch...
214
215
216
217
218
219
220
221
222
223
224
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...
225
class Charge(db.Model, Formable):
2784d9cc   hitier   Add models for ch...
226
227
228
229
    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...
230
    capacity_id = db.Column(db.Integer, db.ForeignKey('capacity.id'))
2784d9cc   hitier   Add models for ch...
231
232
    period_id = db.Column(db.Integer, db.ForeignKey('period.id'))
    charge_rate = db.Column(db.Integer)
12de0b1d   hitier   Now charge add ro...
233

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