class UserDatas(Node): __tablename__ = 'user_datas' __table_args__ = default_table_args __mapper_args__ = {'polymorphic_identity': 'userdata'} id = Column(ForeignKey('node.id'), primary_key=True, info={ 'colanderalchemy': { 'exclude': True, 'title': u"Identifiant Autonomie" }, }) # User account associated with this dataset user_id = Column(ForeignKey('accounts.id'), info={ 'export': { 'exclude': True }, }) user = relationship( "User", primaryjoin='User.id==UserDatas.user_id', info={ 'colanderalchemy': get_excluded_colanderalchemy(u'Compte utilisateur'), 'export': { 'exclude': True }, }) # INFORMATIONS GÉNÉRALES : CF CAHIER DES CHARGES # situation_situation_id = Column(ForeignKey("cae_situation_option.id"), info={ 'colanderalchemy': { 'exclude': True }, }) situation_situation = relationship( "CaeSituationOption", info={ 'colanderalchemy': get_excluded_colanderalchemy(u'Situation dans la CAE'), 'export': { 'related_key': 'label' }, }, ) situation_antenne_id = Column(ForeignKey('antenne_option.id'), info={ 'colanderalchemy': { 'title': u"Antenne de rattachement", "section": u"Synthèse", } }) situation_antenne = relationship( "AntenneOption", info={ 'colanderalchemy': get_excluded_colanderalchemy(u"Antenne de rattachement"), 'export': { 'related_key': 'label' }, }, ) situation_follower_id = Column( ForeignKey('accounts.id'), info={ 'colanderalchemy': { 'title': u'Accompagnateur', 'section': u'Synthèse', }, }, ) situation_follower = relationship( "User", primaryjoin='User.id==UserDatas.situation_follower_id', backref=backref( "followed_contractors", info={ 'colanderalchemy': { 'exclude': True }, 'export': { 'exclude': True }, }, ), info={ 'colanderalchemy': get_excluded_colanderalchemy(u'Conseiller'), 'export': { 'related_key': 'lastname', 'label': u"Conseiller", }, 'import': { 'related_retriever': User.find_user } }) situation_societariat_entrance = Column( Date(), info={ 'colanderalchemy': { 'title': u"Date d'entrée au sociétariat", 'section': u'Synthèse', }, }, default=None, ) # COORDONNÉES : CF CAHIER DES CHARGES # coordonnees_civilite = Column( String(10), info={ 'colanderalchemy': { 'title': u'Civilité', 'section': u"Coordonnées", }, 'export': { 'formatter': lambda val: dict(CIVILITE_OPTIONS).get(val), 'stats': { 'options': CIVILITE_OPTIONS }, } }, default=CIVILITE_OPTIONS[0][0], nullable=False, ) coordonnees_lastname = Column( String(50), info={ 'colanderalchemy': { 'title': u"Nom", 'section': u'Coordonnées', }, }, nullable=False, ) coordonnees_firstname = Column( String(50), info={ 'colanderalchemy': { 'title': u"Prénom", 'section': u'Coordonnées', }, }, nullable=False, ) coordonnees_ladies_lastname = Column( String(50), info={ 'colanderalchemy': { 'title': u"Nom de jeune fille", 'section': u'Coordonnées', }, }, ) coordonnees_email1 = Column( String(100), info={ 'colanderalchemy': { 'title': u"E-mail 1", 'section': u'Coordonnées', } }, nullable=False, ) coordonnees_email2 = Column(String(100), info={ 'colanderalchemy': { 'title': u"E-mail 2", 'section': u'Coordonnées', } }) coordonnees_tel = Column(String(14), info={ 'colanderalchemy': { 'title': u"Tél. fixe", 'section': u'Coordonnées', } }) coordonnees_mobile = Column(String(14), info={ 'colanderalchemy': { 'title': u"Tél. mobile", 'section': u'Coordonnées', } }) coordonnees_address = Column(String(255), info={ 'colanderalchemy': { 'title': u'Adresse', 'section': u'Coordonnées', } }) coordonnees_zipcode = Column(String(7), info={ 'colanderalchemy': { 'title': u'Code postal', 'section': u'Coordonnées', }, 'py3o': { 'formatter': lambda z: u"%05d" % z } }) coordonnees_city = Column( String(100), info={ 'colanderalchemy': { 'title': u"Ville", 'section': u'Coordonnées', } }, ) coordonnees_zone_id = Column(ForeignKey('zone_option.id'), info={ 'colanderalchemy': { 'title': "Zone d'habitation", 'section': u'Coordonnées', }, }) coordonnees_zone = relationship( 'ZoneOption', info={ 'colanderalchemy': get_excluded_colanderalchemy(u"Zone d'habitation"), 'export': { 'related_key': 'label' }, }, ) coordonnees_zone_qual_id = Column( ForeignKey('zone_qualification_option.id'), info={ 'colanderalchemy': { 'title': u"Qualification de la zone d'habitation", 'section': u'Coordonnées', } }) coordonnees_zone_qual = relationship( 'ZoneQualificationOption', info={ 'colanderalchemy': get_excluded_colanderalchemy( u"Qualification de la zone d'habitation"), 'export': { 'related_key': 'label' }, }, ) coordonnees_sex = Column(String(1), info={ 'colanderalchemy': { 'title': u'Sexe', 'section': u'Coordonnées', }, 'export': { 'stats': { 'options': SEX_OPTIONS } }, }) coordonnees_birthday = Column(Date(), info={ 'colanderalchemy': { 'title': u'Date de naissance', 'section': u'Coordonnées', } }) coordonnees_birthplace = Column(String(255), info={ 'colanderalchemy': { 'title': u'Lieu de naissance', 'section': u'Coordonnées', } }) coordonnees_birthplace_zipcode = Column( String(7), info={ 'colanderalchemy': { 'title': u'Code postal de naissance', 'section': u'Coordonnées', } }) coordonnees_nationality = Column(String(50), info={ 'colanderalchemy': { 'title': u'Nationalité', 'section': u'Coordonnées', } }) coordonnees_resident = Column(Date(), info={ 'colanderalchemy': { 'title': u'Carte de séjour (fin de validité)', 'section': u'Coordonnées', } }) coordonnees_secu = Column(String(50), info={ 'colanderalchemy': { 'title': u'Numéro de sécurité sociale', 'section': u'Coordonnées', } }) coordonnees_family_status = Column( String(20), info={ 'colanderalchemy': { 'title': u'Situation de famille', 'section': u'Coordonnées', }, 'export': { 'formatter': lambda val: dict(STATUS_OPTIONS).get(val), 'stats': { 'options': STATUS_OPTIONS }, } }) coordonnees_children = Column(Integer(), default=0, info={ 'colanderalchemy': { 'title': u"Nombre d'enfants", 'section': u'Coordonnées', } }) coordonnees_study_level_id = Column(ForeignKey('study_level_option.id'), info={ 'colanderalchemy': { 'title': u"Niveau d'études", 'section': u'Coordonnées', } }) coordonnees_study_level = relationship( 'StudyLevelOption', info={ 'colanderalchemy': get_excluded_colanderalchemy(u"Niveau d'études"), 'export': { 'related_key': 'label' }, }, ) coordonnees_emergency_name = Column(String(50), info={ 'colanderalchemy': { 'title': u"Contact urgent : Nom", 'section': u'Coordonnées', } }) coordonnees_emergency_phone = Column(String(14), info={ 'colanderalchemy': { 'title': u'Contact urgent : Téléphone', 'section': u'Coordonnées', } }) coordonnees_identifiant_interne = Column( String(20), info={ 'colanderalchemy': { 'title': u'Identifiant interne', 'description': u"Identifiant interne propre à la CAE \ (facultatif)", 'section': u'Coordonnées', } }) # STATUT social_statuses = relationship( "SocialStatusDatas", cascade="all, delete-orphan", primaryjoin="and_(UserDatas.id==SocialStatusDatas.userdatas_id, " "SocialStatusDatas.step=='entry')", order_by="SocialStatusDatas.id", info={ 'colanderalchemy': { 'title': u"Statut social à l'entrée", 'section': u'Statut', }, 'export': { 'label': u"Statut social à l'entrée" } }) today_social_statuses = relationship( "SocialStatusDatas", cascade="all, delete-orphan", primaryjoin="and_(UserDatas.id==SocialStatusDatas.userdatas_id, " "SocialStatusDatas.step=='today')", order_by="SocialStatusDatas.id", info={ 'colanderalchemy': { 'title': u"Statut social actuel", 'section': u'Statut', }, 'export': { 'label': u"Statut social actuel" } }) statut_end_rights_date = Column(Date(), info={ 'colanderalchemy': { 'title': u'Date de fin de droit', 'section': u'Statut', } }) statut_handicap_allocation_expiration = Column( Date(), default=None, info={ 'colanderalchemy': { 'title': u"Allocation adulte handicapé - échéance (expiration)", 'section': u'Statut', } }) statut_external_activity = relationship( "ExternalActivityDatas", cascade="all, delete-orphan", info={ 'colanderalchemy': { 'title': u'Activité externe', 'section': u'Statut', }, 'export': { 'flatten': [ ('type', u"Type de contrat"), ('hours', u'Heures'), ('brut_salary', u"Salaire brut"), ('employer_visited', u"Visite employeur"), ], } }, backref=backref('userdatas', info={ 'export': { 'related_key': u"export_label", "keep_key": True, "label": u"Porteur de projet", "stats": { 'exclude': True }, } }), ) # ACTIVITÉ : cf cahier des charges activity_typologie_id = Column( ForeignKey('activity_type_option.id'), info={ 'colanderalchemy': { 'title': u"Typologie des métiers/secteurs d'activités", 'section': u'Activité', } }) activity_typologie = relationship( 'ActivityTypeOption', info={ 'colanderalchemy': get_excluded_colanderalchemy( u"Typologie des métiers/secteurs d'activités"), 'export': { 'related_key': 'label' }, }, ) activity_pcs_id = Column( ForeignKey('pcs_option.id'), info={'colanderalchemy': { 'title': u"PCS", 'section': u'Activité', }}) activity_pcs = relationship( 'PcsOption', info={ 'colanderalchemy': get_excluded_colanderalchemy(u"PCS"), 'export': { 'related_key': 'label' }, }, ) activity_companydatas = relationship( "CompanyDatas", cascade="all, delete-orphan", backref=backref('userdatas', info={ 'export': { 'related_key': u"export_label", "keep_key": True, "label": u"Porteur de projet", "stats": { 'exclude': True }, } }), info={ 'colanderalchemy': { 'title': u'Activités', 'section': u'Activité', }, 'export': { 'flatten': [ ('title', u"Titre de l'activité"), ('name', u"Nom commercial"), ('website', u"Site internet"), ] } }) # PARCOURS : cf cahier des charges parcours_prescripteur_id = Column(ForeignKey('prescripteur_option.id'), info={ 'colanderalchemy': { 'title': u'Prescripteur', 'section': u'Synthèse', } }) parcours_prescripteur = relationship( "PrescripteurOption", info={ 'colanderalchemy': get_excluded_colanderalchemy(u"Prescripteur"), 'export': { 'related_key': 'label' }, }, ) parcours_prescripteur_name = Column(String(50), info={ 'colanderalchemy': { 'title': u'Nom du prescripteur', 'section': u'Synthèse', } }) parcours_date_info_coll = Column(Date(), info={ 'colanderalchemy': { 'title': u'Date info coll', 'section': u'Synthèse', } }) parcours_non_admission_id = Column( ForeignKey('non_admission_option.id'), info={ 'colanderalchemy': { 'title': u'Motif de non admission en CAE', 'section': u'Synthèse', } }) parcours_non_admission = relationship( "NonAdmissionOption", info={ 'colanderalchemy': get_excluded_colanderalchemy(u'Motif de non admission en CAE'), 'export': { 'related_key': 'label' }, }, ) parcours_goals = Column(Text(), info={ 'colanderalchemy': { 'title': u"Objectifs", "section": u"Activité", } }) parcours_status_id = Column(ForeignKey("parcours_status_option.id"), info={ 'colanderalchemy': { 'title': u"Résultat de la visite médicale", 'section': u'Activité', } }) parcours_status = relationship( "ParcoursStatusOption", info={ 'colanderalchemy': get_excluded_colanderalchemy(u"Résultat de la visite médicale"), 'export': { 'related_key': 'label' }, }, ) parcours_medical_visit = Column(Date(), info={ 'colanderalchemy': { 'title': u"Date de la visite médicale", 'section': u'Activité', } }) parcours_medical_visit_limit = Column(Date(), info={ 'colanderalchemy': { 'title': u"Date limite", 'section': u'Activité', } }) career_paths = relationship( "CareerPath", order_by="desc(CareerPath.start_date)", info={ 'colanderalchemy': { 'exclude': True }, 'export': { 'excldue': True }, }, back_populates='userdatas', ) @property def export_label(self): return u"{0} {1}".format( self.coordonnees_lastname, self.coordonnees_firstname, ) def __unicode__(self): return u"<Userdatas : {0} {1} {2}>".format(self.id, self.coordonnees_lastname, self.coordonnees_firstname) @property def age(self): birthday = self.coordonnees_birthday now = datetime.date.today() years = now.year - birthday.year # We translate the "now" date to know if his birthday has passed or not translated_now = datetime.date(birthday.year, now.month, now.day) if translated_now < birthday: years -= 1 return years def gen_companies(self): """ Generate companies as expected """ from autonomie.models.company import Company companies = [] for data in self.activity_companydatas: # Try to retrieve an existing company (and avoid duplicates) company = Company.query().filter(Company.name == data.name).first() if company is None: company = Company( name=data.name, goal=data.title, email=self.coordonnees_email1, phone=self.coordonnees_tel, mobile=self.coordonnees_mobile, ) if data.activity is not None: company.activities.append(data.activity) company.employees.append(self.user) companies.append(company) return companies def get_cae_situation_from_career_path(self, date): """ Return the CaeSituation of the current user at the given date computed from the career path """ from autonomie.models.career_path import CareerPath from autonomie.models.user.userdatas import CaeSituationOption if date is None: date = datetime.date.today() last_situation_path = CareerPath.query( self.id).filter(CareerPath.start_date <= date).filter( CareerPath.cae_situation_id != None).first() if last_situation_path is None: return None else: situation = CaeSituationOption.query().filter( CaeSituationOption.id == last_situation_path.cae_situation_id).first() return situation def get_career_path_by_stages(self): """ Collect CareerPath associated to this instance and stores them by stage name :returns: A dict {'stage': [List of ordered CareerPath]} :rtype: dict """ from autonomie.models.career_path import CareerPath from autonomie.models.career_stage import CareerStage result = {} for stage in CareerStage.query(): result[stage.name] = CareerPath.query( self.id).filter_by(career_stage_id=stage.id).all() return result
class CareerPath(DBBASE): """ Different career path stages """ __colanderalchemy_config__ = { 'title': u"Etape de parcours", 'help_msg': u"", 'validation_msg': u"L'étape de parcours a bien été enregistrée", 'widget': deform_extensions.GridFormWidget(named_grid=CAREER_PATH_GRID) } __tablename__ = 'career_path' __table_args__ = default_table_args id = Column( 'id', Integer, primary_key=True, info={'colanderalchemy': { 'widget': deform.widget.HiddenWidget() }}, ) userdatas_id = Column( ForeignKey('user_datas.id'), info={ 'colanderalchemy': { 'exclude': True }, 'export': { 'label': u"Identifiant Autonomie", 'stats': { 'exclude': True }, } }, ) userdatas = relationship('UserDatas', info={ 'colanderalchemy': { 'exclude': True }, 'export': { 'exclude': True }, }) start_date = Column(Date(), nullable=False, info={'colanderalchemy': { 'title': u"Date d'effet" }}) end_date = Column(Date(), info={'colanderalchemy': { 'title': u"Date d'échéance" }}) career_stage_id = Column( ForeignKey('career_stage.id'), info={'colanderalchemy': { 'title': u"Type d'étape" }}) career_stage = relationship( 'CareerStage', primaryjoin='CareerStage.id==CareerPath.career_stage_id', info={ 'colanderalchemy': get_excluded_colanderalchemy(u'Etape de parcours'), 'export': { 'related_key': 'label' }, }, ) cae_situation_id = Column( ForeignKey('cae_situation_option.id'), info={ 'colanderalchemy': { 'title': u"Nouvelle situation dans la CAE", 'description': u"Lorsque cette étape sera affectée à un \ porteur cette nouvelle situation sera proposée par défaut" } }) cae_situation = relationship( 'CaeSituationOption', primaryjoin='CaeSituationOption.id==CareerPath.cae_situation_id', info={ 'colanderalchemy': get_excluded_colanderalchemy(u'Situation dans la CAE'), 'export': { 'related_key': 'label' }, }, ) stage_type = Column(String(15), info={ 'colanderalchemy': { 'title': u"Type d'étape" }, 'export': { 'formatter': lambda val: dict(STAGE_TYPE_OPTIONS).get(val), 'stats': { 'options': STAGE_TYPE_OPTIONS }, } }) type_contrat_id = Column( ForeignKey('type_contrat_option.id'), info={'colanderalchemy': { 'title': u"Type de contrat" }}) type_contrat = relationship( 'TypeContratOption', info={ 'colanderalchemy': get_excluded_colanderalchemy(u'Type de contrat'), 'export': { 'related_key': 'label' }, }, ) employee_quality_id = Column( ForeignKey('employee_quality_option.id'), info={'colanderalchemy': { 'title': u"Qualité du salarié" }}) employee_quality = relationship( 'EmployeeQualityOption', info={ 'colanderalchemy': get_excluded_colanderalchemy(u"Qualité du salarié"), 'export': { 'related_key': 'label' }, }) taux_horaire = Column(Float(), info={'colanderalchemy': { 'title': u"Taux horaire" }}) num_hours = Column(Float(), info={'colanderalchemy': { 'title': u"Nombre d'heures" }}) goals_amount = Column( Float(), info={'colanderalchemy': { 'title': u"Objectif de CA / d'activité" }}) goals_period = Column(String(15), info={ 'colanderalchemy': { 'title': u"Période de l'objectif" }, 'export': { 'formatter': lambda val: dict(PERIOD_OPTIONS).get(val), 'stats': { 'options': PERIOD_OPTIONS }, } }) amendment_number = Column( Integer(), info={'colanderalchemy': { 'title': u"Numéro de l'avenant" }}) type_sortie_id = Column( ForeignKey('type_sortie_option.id'), info={'colanderalchemy': { 'title': u"Type de sortie" }}) type_sortie = relationship( 'TypeSortieOption', info={ 'colanderalchemy': get_excluded_colanderalchemy(u"Type de sortie"), 'export': { 'related_key': 'label' }, }, ) motif_sortie_id = Column( ForeignKey('motif_sortie_option.id'), info={'colanderalchemy': { 'title': u"Motif de sortie" }}) motif_sortie = relationship( 'MotifSortieOption', info={ 'colanderalchemy': get_excluded_colanderalchemy(u"Motif de sortie"), 'export': { 'related_key': 'label' }, }, ) @classmethod def query(cls, user): q = super(CareerPath, cls).query() q = q.filter(CareerPath.userdatas_id == user) return q.order_by(CareerPath.start_date.desc())
class SocialStatusDatas(DBBASE): """ Used to store multiple social status """ __tablename__ = 'social_status_datas' __table_args__ = default_table_args __colanderalchemy_config__ = { 'title': u"un statut social", } id = Column(Integer, primary_key=True, info={ 'colanderalchemy': { 'widget': deform.widget.HiddenWidget(), 'missing': None }, 'export': { 'exclude': True }, }) # Is the status relative to 'entry' or 'today' step = Column(String(15), info={'export': {'exclude': True}}) userdatas_id = Column(ForeignKey("user_datas.id"), info={ 'colanderalchemy': { 'exclude': True }, 'export': { 'label': u"Identifiant autonomie", 'stats': { 'exclude': True }, } }) userdatas = relationship("UserDatas", back_populates='social_statuses', info={ 'colanderalchemy': { 'exclude': True }, 'export': { 'related_key': u"export_label", "keep_key": True, "label": u"Statuts sociaux", "stats": { 'exclude': False }, } }) social_status_id = Column( ForeignKey("social_status_option.id"), nullable=False, info={'colanderalchemy': { 'title': u"Statut social" }}) social_status = relationship( "SocialStatusOption", info={ 'colanderalchemy': get_excluded_colanderalchemy(u"Statut social"), 'export': { 'related_key': 'label' } })
class CareerStage(DBBASE): """ Different career stages """ __colanderalchemy_config__ = { 'validation_msg': u"Les étapes de parcours ont bien été configurées", 'widget': deform_extensions.GridFormWidget(named_grid=CAREER_STAGE_GRID) } __tablename__ = 'career_stage' __table_args__ = default_table_args id = Column( 'id', Integer, primary_key=True, info={'colanderalchemy': { 'widget': deform.widget.HiddenWidget() }}, ) active = Column( Boolean(), default=True, info={'colanderalchemy': { 'exclude': True }}, ) name = Column( "name", String(100), nullable=False, info={'colanderalchemy': { 'title': u"Libellé de l'étape" }}, ) cae_situation_id = Column( ForeignKey("cae_situation_option.id"), info={ 'colanderalchemy': { 'title': u"Nouvelle situation dans la CAE", 'description': u"Lorsque cette étape sera affectée à un \ porteur de projet cette situation lui sera automatiquement attribuée" } }) cae_situation = relationship( "CaeSituationOption", primaryjoin='CaeSituationOption.id==CareerStage.cae_situation_id', info={ 'colanderalchemy': get_excluded_colanderalchemy(u'Situation dans la CAE'), 'export': { 'related_key': 'label' }, }, ) stage_type = Column(String(15), info={ 'colanderalchemy': { 'title': u"Type d'étape" }, 'export': { 'formatter': lambda val: dict(STAGE_TYPE_OPTIONS).get(val), 'stats': { 'options': STAGE_TYPE_OPTIONS }, } }) @classmethod def query(cls, include_inactive=False): q = super(CareerStage, cls).query() if not include_inactive: q = q.filter(CareerStage.active == True) return q.order_by('name')
class User(DBBASE, PersistentACLMixin): """ User model """ __tablename__ = 'accounts' __table_args__ = default_table_args id = Column( Integer, primary_key=True, info={'colanderalchemy': { 'exclude': True }}, ) civilite = Column( String(10), info={'colanderalchemy': { 'title': u'Civilité', }}, default=CIVILITE_OPTIONS[0][0], nullable=False, ) lastname = Column( String(50), info={'colanderalchemy': { 'title': u'Nom' }}, nullable=False, ) firstname = Column( String(50), info={'colanderalchemy': { 'title': u'Prénom' }}, nullable=False, ) email = deferred( Column( String(100), info={'colanderalchemy': { 'title': u"Adresse e-mail", }}, nullable=False, ), group='edit', ) companies = relationship( "Company", secondary=COMPANY_EMPLOYEE, info={ 'colanderalchemy': get_excluded_colanderalchemy(u'Entreprises'), 'export': { 'exclude': True } }, ) compte_tiers = deferred( Column( String(30), info={ 'colanderalchemy': { 'title': u'Compte tiers utilisé pour les notes de dépenses', } }, default="", ), group="edit", ) vehicle = deferred( Column( String(66), # 50 + 1 + 15 nullable=True, info={ 'colanderalchemy': { 'title': u'Type de véhicule', 'description': (u"Permet de restreindre les frais " u"kilométriques déclarables par l'entrepreneur"), } }, )) session_datas = deferred(Column( JsonEncodedDict, info={ 'colanderalchemy': { 'exclude': True }, 'export': { 'exclude': True } }, default=None, ), group="edit") userdatas = relationship("UserDatas", primaryjoin='User.id==UserDatas.user_id', back_populates='user', uselist=False, cascade='all, delete-orphan', info={ 'colanderalchemy': { 'exclude': True }, 'export': { 'exclude': True }, }) trainerdatas = relationship("TrainerDatas", back_populates="user", uselist=False, cascade='all, delete-orphan', info={ 'colanderalchemy': { 'exclude': True }, 'export': { 'exclude': True }, }) login = relationship("Login", back_populates="user", uselist=False, cascade='all, delete-orphan', info={ 'colanderalchemy': { 'exclude': True }, 'export': { 'exclude': True }, }) @classmethod def find_user(cls, value, *args, **kw): """ Try to find a user instance based on the given value :param str value: The value that should match a user """ result = cls.query().join(cls.login).filter_by(login=value).first() if result is None: value = value.split(' ') if len(value) >= 2: firstname = value[-1] lastname = " ".join(value[:-1]) try: query = cls.query() query = query.filter_by(lastname=lastname) query = query.filter_by(firstname=firstname) result = query.one() except: result = None return result def get_company(self, cid): """ Retrieve the user's company with id cid :param int cid: The user's company id :returns: A Company instance :raises: `sqlalchemy.orm.exc.NoResultFound` if no company can be found """ from autonomie.models.company import Company if not isinstance(cid, int): cid = int(cid) query = DBSESSION().query(Company) query = query.filter(Company.employees.any(User.id == self.id)) query = query.filter(Company.id == cid) return query.one() def has_userdatas(self): """ Return True if the current object has userdatas associated to it """ from autonomie.models.user.userdatas import UserDatas query = DBSESSION().query(UserDatas.id) query = query.filter(UserDatas.user_id == self.id) count = query.count() return count >= 1 def __unicode__(self): return u"<User {s.id} '{s.lastname} {s.firstname}'>".format(s=self) def __repr__(self): return self.__unicode__().encode('utf-8') def __json__(self, request): return dict( civilite=self.civilite, lastname=self.lastname, firstname=self.firstname, ) @property def label(self): return format_name(self.firstname, self.lastname) @property def active_companies(self): """ Return only enabled companies """ return [company for company in self.companies if company.active] @property def active_company_ids(self): """ Return only enabled companies ids """ from autonomie.models.company import Company query = DBSESSION().query(COMPANY_EMPLOYEE.c.company_id) query = query.filter(COMPANY_EMPLOYEE.c.account_id == self.id) query = query.join(Company).filter(Company.active == True) return [c[0] for c in query]
class TrainerDatas(Node): __tablename__ = "trainer_datas" __table_args__ = default_table_args __mapper_args__ = {'polymorphic_identity': 'trainerdata'} id = Column(ForeignKey('node.id'), primary_key=True, info={ 'colanderalchemy': { 'exclude': True, 'title': u"Identifiant Autonomie" }, }) # User account associated with this dataset user_id = Column(ForeignKey('accounts.id'), info={ 'export': { 'exclude': True }, }) user = relationship( "User", primaryjoin='User.id==TrainerDatas.user_id', info={ 'colanderalchemy': get_excluded_colanderalchemy(u'Compte utilisateur'), 'export': { 'exclude': True }, }, ) # Profil professionnel specialty = Column(Text(), info={ 'colanderalchemy': { 'title': u"Spécialité", "description": u"Votre spécialité - Votre cœur de métier, \ champ de compétence et domaines d'expertise (3 lignes au maximum)", "section": u"Profil Professionnel", } }) linkedin = Column(String(255), info={ 'colanderalchemy': { 'title': u"Réseau Sociaux - Adresse du profil linkedin", "section": u"Profil Professionnel", } }) viadeo = Column(String(255), info={ 'colanderalchemy': { 'title': u"Réseau Sociaux - Adresse du profil Viadeo", "section": u"Profil Professionnel", } }) career = Column( Text(), info={ 'colanderalchemy': { 'title': u"Votre parcours professionnel en 3 dates ou périodes", "description": u"Par exemple pour date : en 1991 - Par \ exemple pour période : de 1991 à 1995", "section": u"Profil Professionnel", } }) qualifications = Column( Text(), info={ 'colanderalchemy': { 'title': u"Votre qualification ou/et diplôme le plus pertinent", "description": u"2 lignes maximum", "section": u"Profil Professionnel", } }) background = Column(Text(), info={ 'colanderalchemy': { 'title': u"Votre formation de formateur", "section": u"Profil Professionnel", } }) references = Column( Text(), info={ 'colanderalchemy': { 'title': u"Vos références de missions de formation effectuées", "description": u"5 références maximum en mentionnant nom du \ client, contexte de l'intervention, année", "section": u"Profil Professionnel", } }) # Section "Concernant votre activité de formation" motivation = Column( Text(), info={ 'colanderalchemy': { 'title': u"Quelle est votre motivation, pourquoi faites-vous \ de la formation ?", "description": u"3 lignes maximum", "section": u"Concernant votre activité de formation", } }) approach = Column(Text(), info={ 'colanderalchemy': { 'title': u"Concernant votre activité de formation", "description": u"3 lignes maximum, ne pas entrer dans la \ méthodologie", "section": u"Concernant votre activité de formation", } }) # Section: Un petit peu de vous temperament = Column( Text(), info={ 'colanderalchemy': { 'title': u"Caractère", "description": u"1 à 3 lignes, par ex : sens de la créativité, \ aimer les gens et croire en leur potentiel, aime maîtriser son sujet \ parfaitement ...", "section": u"Un petit peu de vous", } }) indulgence = Column(Text(), info={ 'colanderalchemy': { 'title': u"Ce qui vous inspire le plus d'indulgence", "description": u"1 à 3 lignes, par ex : la peur d'un \ environnement ou d'un outil, les difficultés des personnes à s'exprimer, \ l’échec lié à une prise de risque ...", "section": u"Un petit peu de vous", } }) sound = Column(Text(), info={ "colanderalchemy": { "title": u"Le son, le bruit que vous aimez", "description": u"1 à 3 lignes, par ex : le café qui coule le \ matin, le son de l'élastique de ma chemise cartonnée qui contient mon \ programme de formation...", "section": u"Un petit peu de vous", } }) object_ = Column(Text(), info={ "colanderalchemy": { "title": u"Si vous étiez un objet, vous seriez ?", "description": u"1 à 3 lignes, par ex : une agrafeuse pour \ faire du lien, un micro pour écouter, une lampe pour éclairer", "section": u"Un petit peu de vous", } }) active = Column(Boolean(), info={ "colanderalchemy": { "title": u"Fiche active ?", "description": u"Cette fiche formateur est-elle active ?", } })
class Company(DBBASE, PersistentACLMixin): """ Company model Store all company specific stuff (headers, logos, RIB, ...) """ __tablename__ = 'company' __table_args__ = default_table_args id = Column("id", Integer, primary_key=True) name = Column("name", String(150), nullable=False) goal = deferred( Column( "object", String(255), default="", ), group='edit' ) email = deferred( Column( "email", String(255) ), group='edit', ) phone = deferred( Column( "phone", String(20), default="" ), group='edit' ) mobile = deferred( Column( "mobile", String(20) ), group='edit' ) comments = deferred( Column( "comments", Text ), group='edit' ) created_at = deferred( Column( Date(), default=datetime.date.today, nullable=False, ), ) updated_at = deferred( Column( Date(), default=datetime.date.today, onupdate=datetime.date.today, nullable=False, ) ) active = deferred(Column(Boolean(), default=True)) RIB = deferred( Column( "RIB", String(255) ), group='edit' ) IBAN = deferred( Column( "IBAN", String(255) ), group='edit' ) code_compta = deferred( Column( String(30), default="" ), group="edit", ) general_customer_account = deferred( Column( String(255), default="" ), group="edit", ) third_party_customer_account = deferred( Column( String(255), default="" ), group="edit", ) bank_account = deferred( Column( String(255), default="" ), group="edit", ) custom_insurance_rate = deferred( Column(Float), group='edit' ) contribution = deferred( Column(Float), group='edit' ) header_id = Column( ForeignKey('file.id'), info={ 'colanderalchemy': {'exclude': True}, 'export': {'exclude': True} }, ) logo_id = Column( ForeignKey('file.id'), info={ 'colanderalchemy': {'exclude': True}, 'export': {'exclude': True} }, ) cgv = deferred( Column(Text, default=''), group='edit', ) # sequences related, used for counters initialization on migration from # another system (eg: WinScop). Contain the latest index already assigned. month_company_sequence_init_value = deferred( Column(Integer), ) month_company_sequence_init_date = deferred( Column(Date), ) # Relationships header_file = relationship( "File", primaryjoin="File.id==Company.header_id", # backref utilisé pour le calcul des acls backref=backref( "company_header_backref", uselist=False, info={ 'colanderalchemy': {'exclude': True}, 'export': {'exclude': True} }, ), info={ 'colanderalchemy': {'exclude': True}, 'export': {'exclude': True} }, ) logo_file = relationship( "File", primaryjoin="File.id==Company.logo_id", # backref utilisé pour le calcul des acls backref=backref( "company_logo_backref", uselist=False, info={ 'colanderalchemy': {'exclude': True}, 'export': {'exclude': True} }, ), uselist=False, info={ 'colanderalchemy': {'exclude': True}, 'export': {'exclude': True} }, ) activities = relationship( "CompanyActivity", secondary=COMPANY_ACTIVITY, backref=backref( 'companies', info={ 'colanderalchemy': {'exclude': True}, 'export': {'exclude': True}, }, ), info={ 'colanderalchemy': { 'title': u'Activités', }, 'export': {'exclude': True}, }, ) customers = relationship( "Customer", order_by="Customer.code", back_populates="company", info={ 'colanderalchemy': {'exclude': True}, "export": {'exclude': True} } ) projects = relationship( "Project", order_by="Project.id", back_populates="company", info={ 'colanderalchemy': {'exclude': True}, "export": {'exclude': True} }, ) tasks = relationship( "Task", primaryjoin="Task.company_id==Company.id", order_by='Task.date', back_populates="company", info={ 'colanderalchemy': {'exclude': True}, 'export': {'exclude': True}, }, ) employees = relationship( "User", secondary=COMPANY_EMPLOYEE, back_populates="companies", info={ 'colanderalchemy': get_excluded_colanderalchemy(u'Employés'), 'export': {'exclude': True} }, ) sale_catalog = relationship( "SaleProductCategory", order_by="SaleProductCategory.title", back_populates="company", info={ 'export': {'exclude': True}, } ) expense = relationship( "ExpenseSheet", order_by="ExpenseSheet.month", cascade="all, delete-orphan", back_populates="company", info={ 'export': {'exclude': True}, } ) _autonomie_service = CompanyService def get_company_id(self): """ Return the current company id Allows company id access through request's context """ return self.id @property def header(self): return self.header_file @header.setter def header(self, appstruct): if self.header_file is None: from autonomie.models.files import File self.header_file = File() appstruct['filename'] = appstruct['name'] = 'header.png' appstruct['mimetype'] = 'image/png' for key, value in appstruct.items(): setattr(self.header_file, key, value) self.header_file.description = 'Header' @property def logo(self): return self.logo_file @logo.setter def logo(self, appstruct): if self.logo_file is None: from autonomie.models.files import File self.logo_file = File() self.logo_file.name = appstruct.get('name', 'logo.png') for key, value in appstruct.items(): setattr(self.logo_file, key, value) self.logo_file.description = 'Logo' @classmethod def query(cls, keys=None, active=True): """ Return a query """ if keys: query = DBSESSION().query(*keys) else: query = super(Company, cls).query() if active: query = query.filter(cls.active == True) return query.order_by(cls.name) def __json__(self, request): """ return a dict representation """ customers = [customer.__json__(request) for customer in self.customers] projects = [project.__json__(request) for project in self.projects] return dict(id=self.id, name=self.name, goal=self.goal, email=self.email, phone=self.phone, mobile=self.mobile, comments=self.comments, RIB=self.RIB, IBAN=self.IBAN, customers=customers, projects=projects) def get_tasks(self): """ Get all tasks for this company, as a list """ return self._autonomie_service.get_tasks(self) def get_recent_tasks(self, page_nb, nb_per_page): """ :param int nb_per_page: how many to return :param int page_nb: pagination index .. todo:: this is naive, use sqlalchemy pagination :return: pagination for wanted tasks, total nb of tasks """ count = self.get_tasks().count() offset = page_nb * nb_per_page items = self._autonomie_service.get_tasks( self, offset=offset, limit=nb_per_page ) return items, count def get_estimations(self, valid=False): """ Return the estimations of the current company """ return self._autonomie_service.get_estimations(self, valid) def get_invoices(self, valid=False): """ Return the invoices of the current company """ return self._autonomie_service.get_invoices(self, valid) def get_cancelinvoices(self, valid=False): """ Return the cancelinvoices of the current company """ return self._autonomie_service.get_cancelinvoices(self, valid) def has_invoices(self): """ return True if this company owns invoices """ return self.get_invoices(self, valid=True).count() > 0 or \ self.get_cancelinvoices(self, valid=True).count() > 0 def get_real_customers(self, year): """ Return the real customers (with invoices) """ return self._autonomie_service.get_customers(self, year) def get_late_invoices(self): """ Return invoices waiting for more than 45 days """ return self._autonomie_service.get_late_invoices(self) def get_customer_codes_and_names(self): """ Return current company's customer codes and names """ return self._autonomie_service.get_customer_codes_and_names(self) def get_project_codes_and_names(self): """ Return current company's project codes and names """ return self._autonomie_service.get_project_codes_and_names(self) def get_next_estimation_index(self): """ Return the next estimation index """ return self._autonomie_service.get_next_estimation_index(self) def get_next_invoice_index(self): """ Return the next invoice index """ return self._autonomie_service.get_next_invoice_index(self) def get_next_cancelinvoice_index(self): """ Return the next cancelinvoice index """ return self._autonomie_service.get_next_cancelinvoice_index(self) def get_turnover(self, year): """ Retrieve the annual turnover for the current company :param int year: The current year """ ca = self._autonomie_service.get_turnover(self, year) return math_utils.integer_to_amount(ca, precision=5) @classmethod def label_query(cls): return cls._autonomie_service.label_query(cls) @classmethod def get_id_by_analytical_account(cls, analytical_account): return cls._autonomie_service.get_id_by_analytical_account( cls, analytical_account )