Files
shopdb-flask/shopdb/core/models/application.py
cproudlock a58feebe7a Fix software-compliance report + relationshiptypes zero-dates
- Add applications.isrequired (model + migration 7c02 + create/update + form
  checkbox). The software-compliance report compared required apps against
  installs but no such flag existed, so it 500'd; now it works.
- Repair relationshiptypes rows with 0000-00-00 createddate/modifieddate
  (partof/connectedto) to real timestamps.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 10:11:24 -04:00

104 lines
3.6 KiB
Python

"""Application tracking models."""
from shopdb.extensions import db
from .base import BaseModel
class AppOwner(BaseModel):
"""Application owner/contact."""
__tablename__ = 'appowners'
appownerid = db.Column(db.Integer, primary_key=True)
appowner = db.Column(db.String(100), nullable=False)
sso = db.Column(db.String(50))
email = db.Column(db.String(100))
# Relationships
supportteams = db.relationship('SupportTeam', back_populates='owner', lazy='dynamic')
def __repr__(self):
return f"<AppOwner {self.appowner}>"
class SupportTeam(BaseModel):
"""Application support team."""
__tablename__ = 'supportteams'
supportteamid = db.Column(db.Integer, primary_key=True)
teamname = db.Column(db.String(100), nullable=False)
teamurl = db.Column(db.String(255))
appownerid = db.Column(db.Integer, db.ForeignKey('appowners.appownerid'))
# Relationships
owner = db.relationship('AppOwner', back_populates='supportteams')
applications = db.relationship('Application', back_populates='supportteam', lazy='dynamic')
def __repr__(self):
return f"<SupportTeam {self.teamname}>"
class Application(BaseModel):
"""Application catalog."""
__tablename__ = 'applications'
appid = db.Column(db.Integer, primary_key=True)
appname = db.Column(db.String(100), unique=True, nullable=False)
appdescription = db.Column(db.String(255))
supportteamid = db.Column(db.Integer, db.ForeignKey('supportteams.supportteamid'))
isinstallable = db.Column(db.Boolean, default=False)
applicationnotes = db.Column(db.Text)
installpath = db.Column(db.String(255))
applicationlink = db.Column(db.String(512))
documentationpath = db.Column(db.String(512))
ishidden = db.Column(db.Boolean, default=False)
isprinter = db.Column(db.Boolean, default=False)
islicenced = db.Column(db.Boolean, default=False)
isrequired = db.Column(
db.Boolean, default=False,
comment='Required on all PCs (drives the software-compliance report)'
)
image = db.Column(db.String(255))
# Relationships
supportteam = db.relationship('SupportTeam', back_populates='applications')
versions = db.relationship('AppVersion', back_populates='application', lazy='dynamic')
def __repr__(self):
return f"<Application {self.appname}>"
class AppVersion(db.Model):
"""Application version tracking."""
__tablename__ = 'appversions'
appversionid = db.Column(db.Integer, primary_key=True)
appid = db.Column(db.Integer, db.ForeignKey('applications.appid'), nullable=False)
version = db.Column(db.String(50), nullable=False)
releasedate = db.Column(db.Date)
notes = db.Column(db.String(255))
dateadded = db.Column(db.DateTime, default=db.func.now())
isactive = db.Column(db.Boolean, default=True)
# Relationships
application = db.relationship('Application', back_populates='versions')
# Unique constraint on app + version
__table_args__ = (
db.UniqueConstraint('appid', 'version', name='uq_app_version'),
)
def to_dict(self):
"""Convert to dictionary."""
return {
'appversionid': self.appversionid,
'appid': self.appid,
'version': self.version,
'releasedate': self.releasedate.isoformat() if self.releasedate else None,
'notes': self.notes,
'dateadded': self.dateadded.isoformat() + 'Z' if self.dateadded else None,
'isactive': self.isactive
}
def __repr__(self):
return f"<AppVersion {self.application.appname if self.application else self.appid} v{self.version}>"