"""Notifications plugin models - adapted to existing database schema.""" from datetime import datetime from shopdb.extensions import db class NotificationType(db.Model): """ Notification type classification. Matches existing notificationtypes table. """ __tablename__ = 'notificationtypes' notificationtypeid = db.Column(db.Integer, primary_key=True) typename = db.Column(db.String(50), nullable=False) typedescription = db.Column(db.Text) typecolor = db.Column(db.String(20), default='#17a2b8') isactive = db.Column(db.Boolean, default=True) def __repr__(self): return f"" def to_dict(self): return { 'notificationtypeid': self.notificationtypeid, 'typename': self.typename, 'typedescription': self.typedescription, 'typecolor': self.typecolor, 'isactive': self.isactive } class Notification(db.Model): """ Notification/announcement model. Matches existing notifications table schema. """ __tablename__ = 'notifications' notificationid = db.Column(db.Integer, primary_key=True) notificationtypeid = db.Column( db.Integer, db.ForeignKey('notificationtypes.notificationtypeid'), nullable=True ) businessunitid = db.Column(db.Integer, nullable=True) appid = db.Column(db.Integer, nullable=True) notification = db.Column(db.Text, nullable=False, comment='The message content') starttime = db.Column(db.DateTime, nullable=True) endtime = db.Column(db.DateTime, nullable=True) ticketnumber = db.Column(db.String(50), nullable=True) link = db.Column(db.String(500), nullable=True) isactive = db.Column(db.Boolean, default=True) isshopfloor = db.Column(db.Boolean, default=False) employeesso = db.Column(db.String(100), nullable=True) employeename = db.Column(db.String(100), nullable=True) # Relationships notificationtype = db.relationship('NotificationType', backref='notifications') def __repr__(self): return f"" @property def is_current(self): """Check if notification is currently active based on dates.""" now = datetime.utcnow() if not self.isactive: return False if self.starttime and now < self.starttime: return False if self.endtime and now > self.endtime: return False return True @property def title(self): """Get title - first line or first 100 chars of notification.""" if not self.notification: return '' lines = self.notification.split('\n') return lines[0][:100] if lines else self.notification[:100] def to_dict(self): """Convert to dictionary with related data.""" result = { 'notificationid': self.notificationid, 'notificationtypeid': self.notificationtypeid, 'businessunitid': self.businessunitid, 'appid': self.appid, 'notification': self.notification, 'title': self.title, 'message': self.notification, 'starttime': self.starttime.isoformat() if self.starttime else None, 'endtime': self.endtime.isoformat() if self.endtime else None, 'startdate': self.starttime.isoformat() if self.starttime else None, 'enddate': self.endtime.isoformat() if self.endtime else None, 'ticketnumber': self.ticketnumber, 'link': self.link, 'linkurl': self.link, 'isactive': bool(self.isactive) if self.isactive is not None else True, 'isshopfloor': bool(self.isshopfloor) if self.isshopfloor is not None else False, 'employeesso': self.employeesso, 'employeename': self.employeename, 'iscurrent': self.is_current } # Add type info if self.notificationtype: result['typename'] = self.notificationtype.typename result['typecolor'] = self.notificationtype.typecolor return result def to_calendar_event(self): """Convert to FullCalendar event format.""" # Map Bootstrap color names to hex colors color_map = { 'success': '#04b962', 'warning': '#ff8800', 'danger': '#f5365c', 'info': '#14abef', 'primary': '#7934f3', 'secondary': '#94614f', 'recognition': '#14abef', # Blue for recognition } raw_color = self.notificationtype.typecolor if self.notificationtype else 'info' # Use mapped color if it's a Bootstrap name, otherwise use as-is (hex) color = color_map.get(raw_color, raw_color if raw_color.startswith('#') else '#14abef') # For recognition notifications, include employee name (or SSO as fallback) in title title = self.title if raw_color == 'recognition': employee_display = self.employeename or self.employeesso if employee_display: title = f"{employee_display}: {title}" return { 'id': self.notificationid, 'title': title, 'start': self.starttime.isoformat() if self.starttime else None, 'end': self.endtime.isoformat() if self.endtime else None, 'allDay': True, 'backgroundColor': color, 'borderColor': color, 'extendedProps': { 'notificationid': self.notificationid, 'message': self.notification, 'typename': self.notificationtype.typename if self.notificationtype else None, 'typecolor': raw_color, 'linkurl': self.link, 'ticketnumber': self.ticketnumber, 'employeename': self.employeename, 'employeesso': self.employeesso, } }