class Project(db.Model, BaseMixin, SerializerMixin): """ Describes a CG production the studio works on. """ name = db.Column(db.String(80), nullable=False, unique=True, index=True) code = db.Column(db.String(80)) description = db.Column(db.String(200)) shotgun_id = db.Column(db.Integer) file_tree = db.Column(JSONB) data = db.Column(JSONB) has_avatar = db.Column(db.Boolean(), default=False) fps = db.Column(db.String(10)) ratio = db.Column(db.String(10)) resolution = db.Column(db.String(12)) production_type = db.Column(db.String(20), default="short") start_date = db.Column(db.Date()) end_date = db.Column(db.Date()) man_days = db.Column(db.Integer) project_status_id = db.Column( UUIDType(binary=False), db.ForeignKey('project_status.id'), index=True ) team = db.relationship( "Person", secondary="project_person_link" )
class ScheduleItem(db.Model, BaseMixin, SerializerMixin): """ Allow to set a start date and an end date for a task type and a project. This information allows to build a schedule for the project. """ start_date = db.Column(db.Date()) end_date = db.Column(db.Date()) man_days = db.Column(db.Integer) project_id = db.Column(UUIDType(binary=False), db.ForeignKey('project.id'), index=True) task_type_id = db.Column(UUIDType(binary=False), db.ForeignKey('task_type.id'), index=True) entity_id = db.Column(UUIDType(binary=False), db.ForeignKey('task_type.id'), index=True) # Sequence or Episode def present(self): return fields.serialize_dict({ "id": self.id, "start_date": self.start_date, "end_date": self.end_date, "man_days": self.man_days, "project_id": self.project_id, "task_type_id": self.task_type_id })
class Project(db.Model, BaseMixin, SerializerMixin): """ Describes a CG production the studio works on. """ name = db.Column(db.String(80), nullable=False, unique=True, index=True) code = db.Column(db.String(80)) description = db.Column(db.String(200)) shotgun_id = db.Column(db.Integer) file_tree = db.Column(JSONB) data = db.Column(JSONB) has_avatar = db.Column(db.Boolean(), default=False) fps = db.Column(db.String(10)) ratio = db.Column(db.String(10)) resolution = db.Column(db.String(12)) production_type = db.Column(db.String(20), default="short") start_date = db.Column(db.Date()) end_date = db.Column(db.Date()) man_days = db.Column(db.Integer) project_status_id = db.Column(UUIDType(binary=False), db.ForeignKey("project_status.id"), index=True) team = db.relationship("Person", secondary="project_person_link") def set_team(self, person_ids): for person_id in person_ids: link = ProjectPersonLink.query.filter_by( project_id=self.id, person_id=person_id).first() if link is None: link = ProjectPersonLink(project_id=self.id, person_id=person_id) db.session.add(link) db.session.commit() @classmethod def create_from_import(cls, data): previous_project = cls.get(data["id"]) person_ids = data.get("team", None) del data["team"] del data["type"] if "project_status_name" in data: del data["project_status_name"] if previous_project is None: previous_project = cls.create(**data) previous_project.save() else: previous_project.update(data) previous_project.save() if person_ids is not None: previous_project.set_team(person_ids) return previous_project
class Milestone(db.Model, BaseMixin, SerializerMixin): """ Allow to set a milestone date to the production schedule. """ date = db.Column(db.Date()) name = db.Column(db.String(40), nullable=False) project_id = db.Column( UUIDType(binary=False), db.ForeignKey("project.id"), index=True ) task_type_id = db.Column( UUIDType(binary=False), db.ForeignKey("task_type.id"), index=True ) def present(self): return fields.serialize_dict( { "id": self.id, "date": self.date, "name": self.name, "project_id": self.project_id, "task_type_id": self.task_type_id, } )
class Person(db.Model, BaseMixin, SerializerMixin): first_name = db.Column(db.String(80), nullable=False) last_name = db.Column(db.String(80), nullable=False) email = db.Column(EmailType, unique=True) phone = db.Column(db.String(30)) active = db.Column(db.Boolean(), default=True) last_presence = db.Column(db.Date()) password = db.Column(db.Binary(60)) shotgun_id = db.Column(db.Integer, unique=True) timezone = db.Column(TimezoneType(backend="pytz"), default=pytz_timezone("Europe/Paris")) locale = db.Column(LocaleType, default=Locale("en", "US")) data = db.Column(JSONB) skills = db.relationship("Department", secondary=department_link) def __repr__(self): return "<Person %s>" % self.full_name() def full_name(self): if sys.version_info[0] < 3: return "%s %s" % (self.first_name.encode("utf-8"), self.last_name.encode("utf-8")) else: return "%s %s" % (self.first_name, self.last_name)
class ScheduleItem(db.Model, BaseMixin, SerializerMixin): """ Allow to set a start date and an end date for a task type and a project. This information allows to build a schedule for the project. """ start_date = db.Column(db.Date()) end_date = db.Column(db.Date()) man_days = db.Column(db.Integer) project_id = db.Column( UUIDType(binary=False), db.ForeignKey("project.id"), index=True ) task_type_id = db.Column( UUIDType(binary=False), db.ForeignKey("task_type.id"), index=True ) object_id = db.Column( UUIDType(binary=False), index=True ) # Sequence or Episode or Asset Type __table_args__ = ( db.UniqueConstraint( "project_id", "task_type_id", "object_id", name="schedule_item_uc", ), ) def present(self): return fields.serialize_dict( { "id": self.id, "start_date": self.start_date, "end_date": self.end_date, "man_days": self.man_days, "project_id": self.project_id, "task_type_id": self.task_type_id, "object_id": self.object_id, } )
class Person(db.Model, BaseMixin, SerializerMixin): """ Describe a member of the studio (and an API user). """ first_name = db.Column(db.String(80), nullable=False) last_name = db.Column(db.String(80), nullable=False) email = db.Column(EmailType, unique=True) phone = db.Column(db.String(30)) active = db.Column(db.Boolean(), default=True) last_presence = db.Column(db.Date()) password = db.Column(db.Binary(60)) desktop_login = db.Column(db.String(80)) shotgun_id = db.Column(db.Integer, unique=True) timezone = db.Column( TimezoneType(backend="pytz"), default=pytz_timezone("Europe/Paris") ) locale = db.Column(LocaleType, default=Locale("en", "US")) data = db.Column(JSONB) role = db.Column(db.String(30), default="user") has_avatar = db.Column(db.Boolean(), default=False) skills = db.relationship( "Department", secondary=department_link ) def __repr__(self): if sys.version_info[0] < 3: return "<Person %s>" % self.full_name().encode("utf-8") else: return "<Person %s>" % self.full_name() def full_name(self): return "%s %s" % ( self.first_name, self.last_name ) def serialize(self, obj_type="Person"): data = SerializerMixin.serialize(self, "Person") data["full_name"] = self.full_name() return data def serialize_safe(self): data = SerializerMixin.serialize(self, "Person") data["full_name"] = self.full_name() del data["password"] return data
class Project(db.Model, BaseMixin, SerializerMixin): """ Describes a CG production the studio works on. """ name = db.Column(db.String(80), nullable=False, unique=True, index=True) code = db.Column(db.String(80)) description = db.Column(db.Text()) shotgun_id = db.Column(db.Integer) file_tree = db.Column(JSONB) data = db.Column(JSONB) has_avatar = db.Column(db.Boolean(), default=False) fps = db.Column(db.String(10)) ratio = db.Column(db.String(10)) resolution = db.Column(db.String(12)) production_type = db.Column(db.String(20), default="short") start_date = db.Column(db.Date()) end_date = db.Column(db.Date()) man_days = db.Column(db.Integer) nb_episodes = db.Column(db.Integer, default=0) episode_span = db.Column(db.Integer, default=0) project_status_id = db.Column( UUIDType(binary=False), db.ForeignKey("project_status.id"), index=True ) team = db.relationship("Person", secondary="project_person_link") asset_types = db.relationship( "EntityType", secondary="project_asset_type_link" ) task_statuses = db.relationship( "TaskStatus", secondary="project_task_status_link" ) task_types = db.relationship( "TaskType", secondary="project_task_type_link" ) def set_team(self, person_ids): for person_id in person_ids: link = ProjectPersonLink.query.filter_by( project_id=self.id, person_id=person_id ).first() if link is None: link = ProjectPersonLink( project_id=self.id, person_id=person_id ) db.session.add(link) db.session.commit() def set_task_types(self, task_type_ids): return self.set_links( task_type_ids, ProjectTaskTypeLink, "project_id", "task_type_id" ) def set_task_statuses(self, task_status_ids): return self.set_links( task_status_ids, ProjectTaskStatusLink, "project_id", "task_status_id", ) def set_asset_types(self, asset_type_ids): return self.set_links( asset_type_ids, ProjectAssetTypeLink, "project_id", "asset_type_id" ) @classmethod def create_from_import(cls, data): is_update = False previous_project = cls.get(data["id"]) data.pop("team", None) data.pop("type", None) data.pop("project_status_name", None) person_ids = data.pop("team", None) task_type_ids = data.pop("task_types", None) task_status_ids = data.pop("task_statuses", None) asset_type_ids = data.pop("asset_types", None) if previous_project is None: previous_project = cls.create(**data) previous_project.save() else: is_update = True previous_project.update(data) previous_project.save() if person_ids is not None: previous_project.set_team(person_ids) if task_type_ids is not None: previous_project.set_task_types(task_type_ids) if task_status_ids is not None: previous_project.set_task_statuses(task_status_ids) if asset_type_ids is not None: previous_project.set_asset_types(asset_type_ids) return (previous_project, is_update)
class Person(db.Model, BaseMixin, SerializerMixin): """ Describe a member of the studio (and an API user). """ first_name = db.Column(db.String(80), nullable=False) last_name = db.Column(db.String(80), nullable=False) email = db.Column(EmailType, unique=True) phone = db.Column(db.String(30)) active = db.Column(db.Boolean(), default=True) last_presence = db.Column(db.Date()) password = db.Column(db.LargeBinary(60)) desktop_login = db.Column(db.String(80)) shotgun_id = db.Column(db.Integer, unique=True) timezone = db.Column( TimezoneType(backend="pytz"), default=pytz_timezone(config.DEFAULT_TIMEZONE), ) locale = db.Column(LocaleType, default=Locale("en", "US")) data = db.Column(JSONB) role = db.Column(db.String(30), default="user") has_avatar = db.Column(db.Boolean(), default=False) notifications_enabled = db.Column(db.Boolean(), default=False) notifications_slack_enabled = db.Column(db.Boolean(), default=False) notifications_slack_userid = db.Column(db.String(60), default="") notifications_mattermost_enabled = db.Column(db.Boolean(), default=False) notifications_mattermost_userid = db.Column(db.String(60), default="") notifications_discord_enabled = db.Column(db.Boolean(), default=False) notifications_discord_userid = db.Column(db.String(60), default="") departments = db.relationship("Department", secondary=department_link, lazy="joined") def __repr__(self): if sys.version_info[0] < 3: return "<Person %s>" % self.full_name().encode("utf-8") else: return "<Person %s>" % self.full_name() def full_name(self): return "%s %s" % (self.first_name, self.last_name) def serialize(self, obj_type="Person", relations=False): data = SerializerMixin.serialize(self, "Person", relations=relations) data["full_name"] = self.full_name() return data def serialize_safe(self, relations=False): data = SerializerMixin.serialize(self, "Person", relations=relations) data["full_name"] = self.full_name() del data["password"] return data def present_minimal(self, relations=False): data = SerializerMixin.serialize(self, "Person", relations=relations) return { "id": data["id"], "first_name": data["first_name"], "last_name": data["last_name"], "full_name": self.full_name(), "has_avatar": data["has_avatar"], "active": data["active"], "departments": data.get("departments", []), "role": data["role"], } def set_departments(self, department_ids): from zou.app.models.department import Department self.departments = [] for department_id in department_ids: department = Department.get(department_id) if department is not None: self.departments.append(department) self.save() @classmethod def create_from_import(cls, person): del person["type"] del person["full_name"] is_update = False previous_person = cls.get(person["id"]) if "password" in person: person["password"] = person["password"].encode() department_ids = None if "departments" in person: department_ids = person.pop("departments", None) if previous_person is None: previous_person = cls.create(**person) else: is_update = True previous_person.update(person) if department_ids is not None: previous_person.set_departments(department_ids) return (previous_person, is_update)
class Person(db.Model, BaseMixin, SerializerMixin): """ Describe a member of the studio (and an API user). """ first_name = db.Column(db.String(80), nullable=False) last_name = db.Column(db.String(80), nullable=False) email = db.Column(EmailType, unique=True) phone = db.Column(db.String(30)) active = db.Column(db.Boolean(), default=True) last_presence = db.Column(db.Date()) password = db.Column(db.LargeBinary(60)) desktop_login = db.Column(db.String(80)) shotgun_id = db.Column(db.Integer, unique=True) timezone = db.Column(TimezoneType(backend="pytz"), default=pytz_timezone("Europe/Paris")) locale = db.Column(LocaleType, default=Locale("en", "US")) data = db.Column(JSONB) role = db.Column(db.String(30), default="user") has_avatar = db.Column(db.Boolean(), default=False) notifications_enabled = db.Column(db.Boolean(), default=False) notifications_slack_enabled = db.Column(db.Boolean(), default=False) notifications_slack_userid = db.Column(db.String(60), default="") skills = db.relationship("Department", secondary=department_link) def __repr__(self): if sys.version_info[0] < 3: return "<Person %s>" % self.full_name().encode("utf-8") else: return "<Person %s>" % self.full_name() def full_name(self): return "%s %s" % (self.first_name, self.last_name) def serialize(self, obj_type="Person", relations=False): data = SerializerMixin.serialize(self, "Person", relations=relations) data["full_name"] = self.full_name() return data def serialize_safe(self, relations=False): data = SerializerMixin.serialize(self, "Person", relations=relations) data["full_name"] = self.full_name() del data["password"] return data def present_minimal(self, relations=False): data = SerializerMixin.serialize(self, "Person", relations=relations) return { "id": data["id"], "first_name": data["first_name"], "last_name": data["last_name"], "full_name": self.full_name(), "has_avatar": data["has_avatar"], "active": data["active"], "desktop_login": data["desktop_login"] } @classmethod def create_from_import(cls, person): del person["type"] del person["full_name"] previous_person = cls.get(person["id"]) if "password" in person: person["password"] = person["password"].encode() if previous_person is None: return (cls.create(**person), False) else: previous_person.update(person) return (previous_person, True)