text: # -*- coding: utf-8 -*-
  from __future__ import unicode_literals
  
  from django.contrib import admin
  
  from import_export.admin import ImportExportModelAdmin
  from import_export.resources import ModelResource
  from import_export.fields import Field
  import import_export.widgets as widgets
  
  from .models import PartCategory, Part
  from .models import PartAttachment, PartStar
  from .models import BomItem
  from .models import PartParameterTemplate, PartParameter
  from .models import PartTestTemplate
  
  from stock.models import StockLocation
  from company.models import SupplierPart
  
  
  class PartResource(ModelResource):
      """ Class for managing Part data import/export """
  
      # ForeignKey fields
      category = Field(attribute='category', widget=widgets.ForeignKeyWidget(PartCategory))
      
      default_location = Field(attribute='default_location', widget=widgets.ForeignKeyWidget(StockLocation))
  
      default_supplier = Field(attribute='default_supplier', widget=widgets.ForeignKeyWidget(SupplierPart))
  
      category_name = Field(attribute='category__name', readonly=True)
      
      variant_of = Field(attribute='variant_of', widget=widgets.ForeignKeyWidget(Part))
  
      suppliers = Field(attribute='supplier_count', readonly=True)
  
      # Extra calculated meta-data (readonly)
      in_stock = Field(attribute='total_stock', readonly=True, widget=widgets.IntegerWidget())
  
      on_order = Field(attribute='on_order', readonly=True, widget=widgets.IntegerWidget())
  
      used_in = Field(attribute='used_in_count', readonly=True, widget=widgets.IntegerWidget())
  
      allocated = Field(attribute='allocation_count', readonly=True, widget=widgets.IntegerWidget())
  
      building = Field(attribute='quantity_being_built', readonly=True, widget=widgets.IntegerWidget())
  
      class Meta:
          model = Part
          skip_unchanged = True
          report_skipped = False
          clean_model_instances = True
          exclude = [
              'bom_checksum', 'bom_checked_by', 'bom_checked_date',
              'lft', 'rght', 'tree_id', 'level',
          ]
  
      def get_queryset(self):
          """ Prefetch related data for quicker access """
  
          query = super().get_queryset()
          query = query.prefetch_related(
              'category',
              'used_in',
              'builds',
              'supplier_parts__purchase_order_line_items',
              'stock_items__allocations'
          )
  
          return query
  
  
  class PartAdmin(ImportExportModelAdmin):
      
      resource_class = PartResource
  
      list_display = ('full_name', 'description', 'total_stock', 'category')
  
      list_filter = ('active', 'assembly', 'is_template', 'virtual')
  
      search_fields = ('name', 'description', 'category__name', 'category__description', 'IPN')
  
  
  class PartCategoryResource(ModelResource):
      """ Class for managing PartCategory data import/export """
  
      parent = Field(attribute='parent', widget=widgets.ForeignKeyWidget(PartCategory))
  
      parent_name = Field(attribute='parent__name', readonly=True)
  
      default_location = Field(attribute='default_location', widget=widgets.ForeignKeyWidget(StockLocation))
  
      class Meta:
          model = PartCategory
          skip_unchanged = True
          report_skipped = False
          clean_model_instances = True
  
          exclude = [
              # Exclude MPTT internal model fields
              'lft', 'rght', 'tree_id', 'level',
          ]
  
      def after_import(self, dataset, result, using_transactions, dry_run, **kwargs):
  
          super().after_import(dataset, result, using_transactions, dry_run, **kwargs)
  
          # Rebuild the PartCategory tree(s)
          PartCategory.objects.rebuild()
  
  
  class PartCategoryAdmin(ImportExportModelAdmin):
  
      resource_class = PartCategoryResource
  
      list_display = ('name', 'pathstring', 'description')
  
      search_fields = ('name', 'description')
  
  
  class PartAttachmentAdmin(admin.ModelAdmin):
  
      list_display = ('part', 'attachment', 'comment')
  
  
  class PartStarAdmin(admin.ModelAdmin):
  
      list_display = ('part', 'user')
  
  
  class PartTestTemplateAdmin(admin.ModelAdmin):
  
      list_display = ('part', 'test_name', 'required')
  
  
  class BomItemResource(ModelResource):
      """ Class for managing BomItem data import/export """
  
      level = Field(attribute='level', readonly=True)
  
      bom_id = Field(attribute='pk')
  
      # ID of the parent part
      parent_part_id = Field(attribute='part', widget=widgets.ForeignKeyWidget(Part))
  
      # IPN of the parent part
      parent_part_ipn = Field(attribute='part__IPN', readonly=True)
  
      # Name of the parent part
      parent_part_name = Field(attribute='part__name', readonly=True)
  
      # ID of the sub-part
      part_id = Field(attribute='sub_part', widget=widgets.ForeignKeyWidget(Part))
  
      # IPN of the sub-part
      part_ipn = Field(attribute='sub_part__IPN', readonly=True)
  
      # Name of the sub-part
      part_name = Field(attribute='sub_part__name', readonly=True)
  
      # Description of the sub-part
      part_description = Field(attribute='sub_part__description', readonly=True)
  
      # Is the sub-part itself an assembly?
      sub_assembly = Field(attribute='sub_part__assembly', readonly=True)
  
      def before_export(self, queryset, *args, **kwargs):
  
          self.is_importing = kwargs.get('importing', False)
  
      def get_fields(self, **kwargs):
          """
          If we are exporting for the purposes of generating
          a 'bom-import' template, there are some fields which
          we are not interested in.
          """
  
          fields = super().get_fields(**kwargs)
  
          # If we are not generating an "import" template,
          # just return the complete list of fields
          if not self.is_importing:
              return fields
  
          # Otherwise, remove some fields we are not interested in
  
          idx = 0
  
          to_remove = [
              'level',
              'bom_id',
              'parent_part_id',
              'parent_part_ipn',
              'parent_part_name',
              'part_description',
              'sub_assembly'
          ]
  
          while idx < len(fields):
  
              if fields[idx].column_name.lower() in to_remove:
                  del fields[idx]
              else:
                  idx += 1
  
          return fields
  
      class Meta:
          model = BomItem
          skip_unchanged = True
          report_skipped = False
          clean_model_instances = True
  
          exclude = [
              'checksum',
              'id',
              'part',
              'sub_part',
          ]
  
  
  class BomItemAdmin(ImportExportModelAdmin):
  
      resource_class = BomItemResource
  
      list_display = ('part', 'sub_part', 'quantity')
  
      search_fields = ('part__name', 'part__description', 'sub_part__name', 'sub_part__description')
  
  
  class ParameterTemplateAdmin(ImportExportModelAdmin):
      list_display = ('name', 'units')
  
  
  class ParameterResource(ModelResource):
      """ Class for managing PartParameter data import/export """
  
      part = Field(attribute='part', widget=widgets.ForeignKeyWidget(Part))
  
      part_name = Field(attribute='part__name', readonly=True)
  
      template = Field(attribute='template', widget=widgets.ForeignKeyWidget(PartParameterTemplate))
  
      template_name = Field(attribute='template__name', readonly=True)
  
      class Meta:
          model = PartParameter
          skip_unchanged = True
          report_skipped = False
          clean_model_instance = True
  
  
  class ParameterAdmin(ImportExportModelAdmin):
  
      resource_class = ParameterResource
  
      list_display = ('part', 'template', 'data')
  
  
  admin.site.register(Part, PartAdmin)
  admin.site.register(PartCategory, PartCategoryAdmin)
  admin.site.register(PartAttachment, PartAttachmentAdmin)
  admin.site.register(PartStar, PartStarAdmin)
  admin.site.register(BomItem, BomItemAdmin)
  admin.site.register(PartParameterTemplate, ParameterTemplateAdmin)
  admin.site.register(PartParameter, ParameterAdmin)
  admin.site.register(PartTestTemplate, PartTestTemplateAdmin)
  