def test_choices_filter(self): from dj.choices import Country self.assertEqual(len(Country()), 235) self.assertEqual(Country(filter=("pl", "gb", "de")), [(73, six.text_type('Germany')), (153, six.text_type('Poland')), (202, six.text_type('United Kingdom'))])
def change_hostname(cls, instances, **kwargs): country_id = kwargs['country'] country_name = Country.name_from_id(int(country_id)).upper() iso3_country_name = iso2_to_iso3(country_name) for instance in instances: instance._try_assign_hostname(country=iso3_country_name, force=True)
def get_user_iso3_country_name(user): """ :param user: instance of django.contrib.auth.models.User which has profile with country attribute """ country_name = Country.name_from_id(int(user.country)) iso3_country_name = iso2_to_iso3(country_name) return iso3_country_name
def get_user_iso3_country_name(user): """ :param user: instance of django.contrib.auth.models.User which has profile with country attribute """ country_name = Country.name_from_id(user.get_profile().country).upper() iso3_country_name = iso2_to_iso3[country_name] return iso3_country_name
class TradeMarkCountry(AdminAbsoluteUrlMixin, models.Model): country = models.PositiveIntegerField(verbose_name=_('trade mark country'), choices=Country(), default=Country.pl.id, null=True, blank=True) def __str__(self): return Country.desc_from_id(self.country)
class Region(AdminAbsoluteUrlMixin, PermissionsForObjectMixin, NamedMixin): country = models.PositiveIntegerField( verbose_name=_('country'), choices=Country(), default=Country.pl.id, ) stocktaking_enabled = models.BooleanField(default=False) """Used for distinguishing the origin of the object by region""" class Permissions: has_access = has_region
def _action_change_hostname(self): for asset in self.assets: country_id = self.kwargs['request'].POST.get('country') country_name = Country.name_from_id(int(country_id)).upper() iso3_country_name = iso2_to_iso3[country_name] template_vars = { 'code': asset.model.category.code, 'country_code': iso3_country_name, } asset.generate_hostname(template_vars=template_vars) asset.save(user=self.logged_user)
def manager_country_attribute_populate(sender, user, ldap_user, **kwargs): try: profile_map = settings.AUTH_LDAP_USER_ATTR_MAP except AttributeError: profile_map = {} if 'manager' in profile_map: if profile_map['manager'] in ldap_user.attrs: manager_ref = force_text( ldap_user.attrs[profile_map['manager']][0]) # CN=John Smith,OU=TOR,OU=Corp-Users,DC=mydomain,DC=internal cn = manager_ref.split(',')[0][3:] user.manager = cn # raw value from LDAP is in profile.country for this reason we assign # some correct value user.country = None if 'country' in profile_map: if profile_map['country'] in ldap_user.attrs: country = force_text(ldap_user.attrs[profile_map['country']][0]) # assign None if `country` doesn't exist in Country try: user.country = Country.id_from_name(country.lower()) except ValueError: user.country = None
class TransitionForm(forms.Form): user = AutoCompleteSelectField( LOOKUPS['asset_user'], required=True, ) warehouse = AutoCompleteSelectField( LOOKUPS['asset_warehouse'], required=True, ) loan_end_date = forms.DateField( required=True, widget=DateWidget(attrs={ 'class': 'end-date-field ', 'placeholder': _('End YYYY-MM-DD'), 'data-collapsed': True, }), label=_('Loan end date'), input_formats=RALPH_DATE_FORMAT_LIST, ) country = forms.ChoiceField( choices=[('', '----')] + Country(), label=_('Country'), required=True, )
def country_code(self): iso2 = Country.name_from_id(int(self.region.country)).upper() return iso2_to_iso3(iso2)
class BackOfficeAsset(Regionalizable, Asset): _allow_in_dashboard = True warehouse = models.ForeignKey(Warehouse, on_delete=models.PROTECT) owner = models.ForeignKey( settings.AUTH_USER_MODEL, null=True, blank=True, related_name='assets_as_owner', ) user = models.ForeignKey( settings.AUTH_USER_MODEL, null=True, blank=True, related_name='assets_as_user', ) location = models.CharField(max_length=128, null=True, blank=True) purchase_order = models.CharField(max_length=50, null=True, blank=True) loan_end_date = models.DateField( null=True, blank=True, default=None, verbose_name=_('Loan end date'), ) status = TransitionField( default=BackOfficeAssetStatus.new.id, choices=BackOfficeAssetStatus(), ) imei = NullableCharField(max_length=18, null=True, blank=True, unique=True, verbose_name=_('IMEI')) imei2 = NullableCharField(max_length=18, null=True, blank=True, unique=True, verbose_name=_('IMEI 2')) office_infrastructure = models.ForeignKey(OfficeInfrastructure, null=True, blank=True) class Meta: verbose_name = _('Back Office Asset') verbose_name_plural = _('Back Office Assets') @property def country_code(self): iso2 = Country.name_from_id(int(self.region.country)).upper() return iso2_to_iso3(iso2) def __str__(self): return '{} (BC: {} / SN: {})'.format(self.hostname or '-', self.barcode or '-', self.sn or '-') def __repr__(self): return '<BackOfficeAsset: {}>'.format(self.id) def validate_imei(self, imei): return IMEI_SINCE_2003.match(imei) or IMEI_UNTIL_2003.match(imei) def clean(self): super().clean() if self.imei and not self.validate_imei(self.imei): raise ValidationError({ 'imei': _('%(imei)s is not IMEI format') % { 'imei': self.imei } }) if self.imei2 and not self.validate_imei(self.imei2): raise ValidationError({ 'imei2': _('%(imei)s is not IMEI format') % { 'imei': self.imei2 } # noqa }) def is_liquidated(self, date=None): date = date or datetime.date.today() # check if asset has status 'liquidated' and if yes, check if it has # this status on given date if (self.status == BackOfficeAssetStatus.liquidated and self._liquidated_at(date)): return True return False def generate_hostname(self, commit=True, template_vars=None): def render_template(template): template = Template(template) context = Context(template_vars or {}) return template.render(context) logger.warning( 'Generating new hostname for {} using {} old hostname {}'.format( self, template_vars, self.hostname)) prefix = render_template(ASSET_HOSTNAME_TEMPLATE.get('prefix', ''), ) postfix = render_template(ASSET_HOSTNAME_TEMPLATE.get('postfix', ''), ) counter_length = ASSET_HOSTNAME_TEMPLATE.get('counter_length', 5) last_hostname = AssetLastHostname.increment_hostname(prefix, postfix) self.hostname = last_hostname.formatted_hostname(fill=counter_length) if commit: self.save() # TODO: add message when hostname was changed def _try_assign_hostname(self, commit=False, country=None, force=False): if self.model.category and self.model.category.code: template_vars = { 'code': self.model.category.code, 'country_code': country or self.country_code, } if (force or not self.hostname or self.country_code not in self.hostname): self.generate_hostname(commit, template_vars) @classmethod def get_autocomplete_queryset(cls): return cls._default_manager.exclude( status=BackOfficeAssetStatus.liquidated.id) @classmethod @transition_action(form_fields={ 'user': { 'field': forms.CharField(label=_('User')), 'autocomplete_field': 'user', 'default_value': partial(autocomplete_user, field_name='user') } }, run_after=['unassign_user']) def assign_user(cls, instances, **kwargs): user = get_user_model().objects.get(pk=int(kwargs['user'])) for instance in instances: instance.user = user @classmethod @transition_action( form_fields={ 'owner': { 'field': forms.CharField(label=_('Owner')), 'autocomplete_field': 'owner', 'default_value': partial(autocomplete_user, field_name='owner') } }, help_text=_( 'During this transition owner will be assigned as well as new ' 'hostname might be generated for asset (only for particular model ' 'categories and only if owner\'s country has changed)'), run_after=['unassign_owner']) def assign_owner(cls, instances, **kwargs): owner = get_user_model().objects.get(pk=int(kwargs['owner'])) for instance in instances: instance.owner = owner @classmethod @transition_action(form_fields={ 'licences': { 'field': forms.ModelMultipleChoiceField( queryset=Licence.objects.all(), label=_('Licence'), required=False, ), 'autocomplete_field': 'licence', 'autocomplete_model': 'licences.BaseObjectLicence', 'widget_options': { 'multi': True }, } }, run_after=['unassign_licences']) def assign_licence(cls, instances, **kwargs): for instance in instances: for obj in kwargs['licences']: BaseObjectLicence.objects.get_or_create( base_object=instance, licence_id=obj.id, ) @classmethod @transition_action(run_after=['loan_report', 'return_report']) def unassign_owner(cls, instances, **kwargs): for instance in instances: kwargs['history_kwargs'][instance.pk]['affected_owner'] = str( instance.owner) instance.owner = None @classmethod @transition_action(run_after=['loan_report', 'return_report']) def unassign_user(cls, instances, **kwargs): for instance in instances: kwargs['history_kwargs'][instance.pk]['affected_user'] = str( instance.user) instance.user = None @classmethod @transition_action( form_fields={ 'loan_end_date': { 'field': forms.DateField( label=_('Loan end date'), widget=forms.TextInput(attrs={'class': 'datepicker'})) } }, ) def assign_loan_end_date(cls, instances, **kwargs): for instance in instances: instance.loan_end_date = kwargs['loan_end_date'] @classmethod @transition_action() def unassign_loan_end_date(cls, instances, **kwargs): for instance in instances: instance.loan_end_date = None @classmethod @transition_action( form_fields={ 'warehouse': { 'field': forms.CharField(label=_('Warehouse')), 'autocomplete_field': 'warehouse' } }) def assign_warehouse(cls, instances, **kwargs): warehouse = Warehouse.objects.get(pk=int(kwargs['warehouse'])) for instance in instances: instance.warehouse = warehouse @classmethod @transition_action( form_fields={ 'office_infrastructure': { 'field': forms.CharField(label=_('Office infrastructure')), 'autocomplete_field': 'office_infrastructure' } }, ) def assign_office_infrastructure(cls, instances, **kwargs): office_inf = OfficeInfrastructure.objects.get( pk=int(kwargs['office_infrastructure'])) for instance in instances: instance.office_infrastructure = office_inf @classmethod @transition_action(form_fields={ 'remarks': { 'field': forms.CharField(label=_('Remarks')), } }) def add_remarks(cls, instances, **kwargs): for instance in instances: instance.remarks = '{}\n{}'.format(instance.remarks, kwargs['remarks']) @classmethod @transition_action(form_fields={ 'task_url': { 'field': forms.URLField(label=_('task URL')), } }) def assign_task_url(cls, instances, **kwargs): for instance in instances: instance.task_url = kwargs['task_url'] @classmethod @transition_action() def unassign_licences(cls, instances, **kwargs): BaseObjectLicence.objects.filter(base_object__in=instances).delete() @classmethod @transition_action( form_fields={ 'country': { 'field': forms.ChoiceField( label=_('Country'), choices=Country(), **{ 'initial': Country.from_name( settings.CHANGE_HOSTNAME_ACTION_DEFAULT_COUNTRY. lower() # noqa: E501 ).id } if settings.CHANGE_HOSTNAME_ACTION_DEFAULT_COUNTRY else {}), } }, ) def change_hostname(cls, instances, **kwargs): country_id = kwargs['country'] country_name = Country.name_from_id(int(country_id)).upper() iso3_country_name = iso2_to_iso3(country_name) for instance in instances: instance._try_assign_hostname(country=iso3_country_name, force=True) @classmethod @transition_action( form_fields={ 'user': { 'field': forms.CharField(label=_('User')), 'autocomplete_field': 'user', }, 'owner': { 'field': forms.CharField(label=_('Owner')), 'autocomplete_field': 'owner', 'condition': lambda obj, actions: bool(obj.owner), } }) def change_user_and_owner(cls, instances, **kwargs): UserModel = get_user_model() # noqa user_id = kwargs.get('user', None) user = UserModel.objects.get(id=user_id) owner_id = kwargs.get('owner', None) for instance in instances: instance.user = user if not owner_id: instance.owner = user else: instance.owner = UserModel.objects.get(id=owner_id) instance.location = user.location @classmethod def _get_report_context(cls, instances): data_instances = [{ 'sn': obj.sn, 'model': str(obj.model), 'imei': obj.imei, 'imei2': obj.imei2, 'barcode': obj.barcode, } for obj in instances] return data_instances @classmethod @transition_action(precondition=_check_assets_owner) def must_be_owner_of_asset(cls, instances, **kwargs): """Only a precondition matters""" pass @classmethod @transition_action(precondition=_check_assets_user) def must_be_user_of_asset(cls, instances, **kwargs): """Only a precondition matters""" pass @classmethod @transition_action( form_fields={ 'accept': { 'field': forms.BooleanField( label=_('I have read and fully understand and ' 'accept the agreement.')) }, }) def accept_asset_release_agreement(cls, instances, requester, **kwargs): pass @classmethod @transition_action(run_after=['release_report']) def assign_requester_as_an_owner(cls, instances, requester, **kwargs): """Assign current user as an owner""" for instance in instances: instance.owner = requester instance.save() @classmethod @transition_action(form_fields={ 'report_language': { 'field': forms.ModelChoiceField( label=_('Release report language'), queryset=ReportLanguage.objects.all().order_by('-default'), empty_label=None), 'exclude_from_history': True } }, return_attachment=True, run_after=['assign_owner', 'assign_user']) def release_report(cls, instances, requester, transition_id, **kwargs): report_name = get_report_name_for_transition_id(transition_id) return generate_report(instances=instances, name=report_name, requester=requester, language=kwargs['report_language'], context=cls._get_report_context(instances)) @classmethod @transition_action( run_after=['release_report', 'return_report', 'loan_report']) def send_attachments_to_user(cls, requester, transition_id, **kwargs): context_func = get_hook('back_office.transition_action.email_context') send_transition_attachments_to_user(requester=requester, transition_id=transition_id, context_func=context_func, **kwargs) @classmethod @transition_action( form_fields={ 'report_language': { 'field': forms.ModelChoiceField( label=_('Return report language'), queryset=ReportLanguage.objects.all().order_by('-default'), empty_label=None), 'exclude_from_history': True }, }, return_attachment=True, precondition=_check_user_assigned, ) def return_report(cls, instances, requester, **kwargs): return generate_report(instances=instances, name='return', requester=requester, language=kwargs['report_language'], context=cls._get_report_context(instances)) @classmethod @transition_action( form_fields={ 'report_language': { 'field': forms.ModelChoiceField( label=_('Loan report language'), queryset=ReportLanguage.objects.all().order_by('-default'), empty_label=None), 'exclude_from_history': True } }, return_attachment=True, run_after=['assign_owner', 'assign_user', 'assign_loan_end_date']) def loan_report(cls, instances, requester, **kwargs): return generate_report(name='loan', requester=requester, instances=instances, language=kwargs['report_language'], context=cls._get_report_context(instances)) @classmethod @transition_action(verbose_name=_('Convert to DataCenter Asset'), disable_save_object=True, only_one_action=True, form_fields={ 'rack': { 'field': forms.CharField(label=_('Rack')), 'autocomplete_field': 'rack', 'autocomplete_model': 'data_center.DataCenterAsset' }, 'position': { 'field': forms.IntegerField(label=_('Position')), }, 'model': { 'field': forms.CharField(label=_('Model')), 'autocomplete_field': 'model', 'autocomplete_model': 'data_center.DataCenterAsset' }, 'service_env': { 'field': forms.CharField(label=_('Service env')), 'autocomplete_field': 'service_env', 'autocomplete_model': 'data_center.DataCenterAsset' } }) def convert_to_data_center_asset(cls, instances, **kwargs): from ralph.data_center.models.physical import DataCenterAsset, Rack # noqa from ralph.back_office.helpers import bo_asset_to_dc_asset_status_converter # noqa with transaction.atomic(): for i, instance in enumerate(instances): data_center_asset = DataCenterAsset() data_center_asset.rack = Rack.objects.get(pk=kwargs['rack']) data_center_asset.position = kwargs['position'] data_center_asset.service_env = ServiceEnvironment.objects.get( pk=kwargs['service_env']) data_center_asset.model = AssetModel.objects.get( pk=kwargs['model']) target_status = int( Transition.objects.values_list('target', flat=True).get( pk=kwargs['transition_id']) # noqa ) data_center_asset.status = bo_asset_to_dc_asset_status_converter( # noqa instance.status, target_status) move_parents_models(instance, data_center_asset, exclude_copy_fields=[ 'rack', 'model', 'service_env', 'status' ]) data_center_asset.save() # Save new asset to list, required to redirect url. # RunTransitionView.get_success_url() instances[i] = data_center_asset @classmethod @transition_action() def assign_hostname_if_empty_or_country_not_match(cls, instances, **kwargs): for instance in instances: instance._try_assign_hostname(commit=False, force=False)
def country_code(self): iso2 = Country.name_from_id(self.owner.profile.country).upper() return iso2_to_iso3.get(iso2, 'POL')
class BasicInfo(db.Model): """Describes a basic user profile that links through a one-to-one field to ``django.contrib.auth.models.User``. Provides fields to store nicks, birth dates, genders, countries of origin, cities and time zones. This model is also a transparent proxy to the User object enabling most of the functionality that would require explicitly getting the user model. This enables for enhanced duck typing in scenarios where user objects are expected.""" user = db.OneToOneField(User) nick = db.CharField( verbose_name=_("visible nick"), blank=True, default='', max_length=30, help_text=_( "Fill this field if you wish to change " "your visible nick. You can use Unicode characters and spaces. " "Keep in mind that your original username (the one you use to " "log into the site) will remain unchanged.")) birth_date = db.DateField(verbose_name=_("birth date"), blank=True, null=True) gender = db.PositiveIntegerField(verbose_name=_("gender"), choices=Gender(), default=Gender.male.id) country = db.PositiveIntegerField(verbose_name=_("country"), choices=Country(), default=Country.pl.id) city = db.CharField(verbose_name=_("city"), max_length=30, blank=True) time_zone = db.FloatField(_('Time zone'), choices=TZ_CHOICES, default=1.0) class Meta: abstract = True def save(self, *args, **kwargs): if not self.nick.strip(): self.nick = self.user.username super(BasicInfo, self).save(*args, **kwargs) def __getattr__(self, name): try: return super(BasicInfo, self).__getattr__(name) except AttributeError: user = None if '_user_cache' in self.__dict__: user = self.__dict__['_user_cache'] if not user: user = User.objects.get(id=self.__dict__['user_id']) self.__dict__['_user_cache'] = user return getattr(user, name) def age(self): """age() -> numeric_age""" if not self.birth_date: return '?' else: return int((date.today() - self.birth_date).days / 365.25) def is_male(self): """True if the gender is male.""" return self.gender == Gender.male.id def is_female(self): """True if the gender is female.""" return self.gender == Gender.female.id def has_gender(self): """True if the gender is set.""" return self.is_male() or self.is_female() def get_country_display_english(self): """Displays the country of origin in its English form. This is useful for distionary lookups.""" return Country.raw_from_id(self.country) def get_profile(self): return self @property def profile(self): return self def is_authenticated(self): return True
def get_country_display_english(self): """Displays the country of origin in its English form. This is useful for distionary lookups.""" return Country.raw_from_id(self.country)
def name(self): return Country.desc_from_id(self.country)
class RalphUser(PermByFieldMixin, AbstractUser, AdminAbsoluteUrlMixin, AutocompleteTooltipMixin): country = models.PositiveIntegerField( verbose_name=_('country'), choices=Country(), default=Country.pl.id, ) city = models.CharField( verbose_name=_("city"), max_length=30, blank=True, ) company = models.CharField( verbose_name=_('company'), max_length=64, blank=True, ) employee_id = models.CharField( verbose_name=_('employee id'), max_length=64, blank=True, ) profit_center = models.CharField( verbose_name=_('profit center'), max_length=1024, blank=True, ) cost_center = models.CharField( verbose_name=_('cost center'), max_length=1024, blank=True, ) department = models.CharField( verbose_name=_('department'), max_length=64, blank=True, ) manager = models.CharField( verbose_name=_('manager'), max_length=1024, blank=True, ) location = models.CharField( verbose_name=_('location'), max_length=128, blank=True, ) segment = models.CharField( verbose_name=_('segment'), max_length=256, blank=True, ) regions = models.ManyToManyField(Region, related_name='users', blank=True) team = models.ForeignKey(Team, null=True, blank=True) autocomplete_tooltip_fields = [ 'employee_id', 'company', 'department', 'manager', 'profit_center', 'cost_center' ] autocomplete_words_split = True class Meta(AbstractUser.Meta): swappable = 'AUTH_USER_MODEL' def __str__(self): full_name = self.get_full_name() if full_name: return '{} ({})'.format(full_name, self.username) return super().__str__() @property def api_token_key(self): try: return self.auth_token.key except Token.DoesNotExist: return None @property def regions_ids(self): """ Get region ids without additional SQL joins. """ return self.regions.through.objects.filter(ralphuser=self).values_list( 'region_id', flat=True) def has_any_perms(self, perms, obj=None): return any([self.has_perm(p, obj=obj) for p in perms]) def save(self, *args, **kwargs): # set default values if None provided for field in ('country', ): val = getattr(self, field) if val is None: val = self._meta.get_field_by_name(field)[0].default setattr(self, field, val) return super().save(*args, **kwargs) @property def autocomplete_str(self): return '{} <i>{}</i>'.format(str(self), self.department) @property def permissions_hash(self): """ Property used in template as a param to cache invalidation. Hash for caching is calculated from user ID and its permissions. """ perms_set = frozenset(self.get_all_permissions()) key = ':'.join((str(self.id), str(hash(perms_set)))) return hashlib.md5(force_bytes(key)).hexdigest()
class TradeMarkCountryFactory(DjangoModelFactory): country = factory.Iterator([x[0] for x in Country()]) class Meta: model = TradeMarkCountry
def country(self): return Country.raw_from_id(self.profile.country)
def __str__(self): return Country.desc_from_id(self.country)