class ExclusionReportDetailSerializer(serializers.ModelSerializer): """ Detail Serializer for the Exclusion Report """ status = ComplianceReportWorkflowStateSerializer(read_only=True) type = ComplianceReportTypeSerializer(read_only=True) organization = OrganizationMinSerializer(read_only=True) compliance_period = CompliancePeriodSerializer(read_only=True) exclusion_agreement = ExclusionAgreementSerializer(read_only=True) history = serializers.SerializerMethodField() def get_history(self, obj): """ Returns all the previous status changes for the credit trade """ from .ComplianceReportHistory import ComplianceReportHistorySerializer history = obj.get_history(["Submitted"]) serializer = ComplianceReportHistorySerializer(history, many=True) return serializer.data class Meta: model = ComplianceReport fields = [ 'id', 'status', 'type', 'organization', 'compliance_period', 'exclusion_agreement', 'read_only', 'history' ]
class ComplianceReportListSerializer(serializers.ModelSerializer): status = SlugRelatedField(slug_field='status', read_only=True) type = SlugRelatedField(slug_field='the_type', read_only=True) organization = OrganizationMinSerializer(read_only=True) compliance_period = CompliancePeriodSerializer(read_only=True) class Meta: model = ComplianceReport fields = ('id', 'status', 'type', 'organization', 'compliance_period', 'update_timestamp')
class ComplianceReportCreateSerializer(serializers.ModelSerializer): status = SlugRelatedField( slug_field='status', queryset=ComplianceReportStatus.objects.filter(status__in=['Draft'])) type = SlugRelatedField(slug_field='the_type', queryset=ComplianceReportType.objects.all()) compliance_period = SlugRelatedField( slug_field='description', queryset=CompliancePeriod.objects.all()) organization = OrganizationMinSerializer(read_only=True) schedule_c = ScheduleCDetailSerializer(allow_null=True, required=False) schedule_a = ScheduleADetailSerializer(allow_null=True, required=False) def create(self, validated_data): schedule_c_data = None if 'schedule_c' in validated_data: schedule_c_data = validated_data.pop('schedule_c') schedule_a_data = None if 'schedule_a' in validated_data: schedule_a_data = validated_data.pop('schedule_a') instance = ComplianceReport.objects.create(**validated_data) if schedule_c_data and 'records' in schedule_c_data: records_data = schedule_c_data.pop('records') schedule_c = ScheduleC.objects.create(**schedule_c_data, compliance_report=instance) instance.schedule_c = schedule_c for record_data in records_data: record = ScheduleCRecord.objects.create(**record_data, schedule=schedule_c) schedule_c.records.add(record) schedule_c.save() if schedule_a_data and 'records' in schedule_a_data: records_data = schedule_a_data.pop('records') schedule_a = ScheduleA.objects.create(**schedule_a_data, compliance_report=instance) instance.schedule_a = schedule_a for record_data in records_data: record = ScheduleARecord.objects.create(**record_data, schedule=schedule_a) schedule_a.records.add(record) schedule_a.save() instance.save() return instance class Meta: model = ComplianceReport fields = ('status', 'type', 'compliance_period', 'organization', 'schedule_a', 'schedule_c')
class ComplianceReportListSerializer(serializers.ModelSerializer): """ Default List serializer for Compliance Reports """ status = ComplianceReportWorkflowStateSerializer(read_only=True) type = SlugRelatedField(slug_field='the_type', read_only=True) organization = OrganizationMinSerializer(read_only=True) compliance_period = CompliancePeriodSerializer(read_only=True) class Meta: model = ComplianceReport fields = ('id', 'status', 'type', 'organization', 'compliance_period', 'update_timestamp', 'has_snapshot', 'read_only')
class ComplianceReportDetailSerializer(serializers.ModelSerializer): status = ComplianceReportStatusSerializer(read_only=True) type = ComplianceReportTypeSerializer(read_only=True) organization = OrganizationMinSerializer(read_only=True) compliance_period = CompliancePeriodSerializer(read_only=True) schedule_a = ScheduleADetailSerializer(read_only=True) schedule_c = ScheduleCDetailSerializer(read_only=True) class Meta: model = ComplianceReport fields = [ 'id', 'status', 'type', 'organization', 'compliance_period', 'schedule_a', 'schedule_c' ]
class ComplianceReportCreateSerializer(serializers.ModelSerializer): """ Create Serializer for the Compliance Report """ status = ComplianceReportWorkflowStateSerializer() type = SlugRelatedField(slug_field='the_type', queryset=ComplianceReportType.objects.all()) compliance_period = SlugRelatedField( slug_field='description', queryset=CompliancePeriod.objects.all()) organization = OrganizationMinSerializer(read_only=True) def validate(self, data): request = self.context.get('request') if not request.user.has_perm('COMPLIANCE_REPORT_MANAGE'): raise PermissionDenied( 'You do not have permission to create a report') return data def validate_status(self, value): if value['fuel_supplier_status'].status not in ['Draft']: raise serializers.ValidationError('Value must be Draft') if 'analyst_status' in value: raise serializers.ValidationError('Cannot set this value') if 'manager_status' in value: raise serializers.ValidationError('Cannot set this value') if 'director_status' in value: raise serializers.ValidationError('Cannot set this value') return value def create(self, validated_data): status_data = validated_data.pop('status') status = ComplianceReportWorkflowState.objects.create(**status_data) return ComplianceReport.objects.create(status=status, **validated_data) def save(self, **kwargs): super().save(**kwargs) request = self.context['request'] self.instance.create_user = request.user self.instance.update_user = request.user self.instance.save() class Meta: model = ComplianceReport fields = ('status', 'type', 'compliance_period', 'organization', 'id') read_only_fields = ('id', )
class ExclusionReportUpdateSerializer(serializers.ModelSerializer): """ Update Serializer for the Compliance Report """ status = ComplianceReportWorkflowStateSerializer(required=False) type = SlugRelatedField(slug_field='the_type', read_only=True) compliance_period = SlugRelatedField(slug_field='description', read_only=True) organization = OrganizationMinSerializer(read_only=True) exclusion_agreement = ExclusionAgreementSerializer(allow_null=True, required=False) def validate_exclusion_agreement(self, data): return data def update(self, instance, validated_data): request = self.context.get('request') if 'status' in validated_data: status_data = validated_data.pop('status') can_change = ComplianceReportPermissions.user_can_change_status( request.user, instance, new_fuel_supplier_status=status_data['fuel_supplier_status']. status if 'fuel_supplier_status' in status_data else None, new_analyst_status=status_data['analyst_status'].status if 'analyst_status' in status_data else None, new_director_status=status_data['director_status'].status if 'director_status' in status_data else None, new_manager_status=status_data['manager_status'].status if 'manager_status' in status_data else None) if not can_change: raise PermissionDenied('Invalid status change') if 'fuel_supplier_status' in status_data: instance.status.fuel_supplier_status = status_data[ 'fuel_supplier_status'] if 'analyst_status' in status_data: instance.status.analyst_status = status_data['analyst_status'] if 'manager_status' in status_data: instance.status.manager_status = status_data['manager_status'] if 'director_status' in status_data: instance.status.director_status = status_data[ 'director_status'] instance.status.save() if 'exclusion_agreement' in validated_data: agreement_data = validated_data.pop('exclusion_agreement') if instance.exclusion_agreement: ExclusionAgreementRecord.objects.filter( exclusion_agreement=instance.exclusion_agreement).delete() exclusion_agreement = instance.exclusion_agreement if 'records' in agreement_data: records_data = agreement_data.pop('records') if not instance.exclusion_agreement: exclusion_agreement = ExclusionAgreement.objects.create( **agreement_data, compliance_report=instance) instance.exclusion_agreement = exclusion_agreement for record_data in records_data: record = ExclusionAgreementRecord.objects.create( **record_data, exclusion_agreement=exclusion_agreement) exclusion_agreement.records.add(record) exclusion_agreement.save() if request: instance.update_user = request.user instance.save() # all other fields are read-only return instance class Meta: model = ComplianceReport fields = ('status', 'type', 'compliance_period', 'organization', 'exclusion_agreement', 'read_only') read_only_fields = ('compliance_period', 'read_only', 'organization')
class ComplianceReportUpdateSerializer(serializers.ModelSerializer, ComplianceReportValidator): """ Update Serializer for the Compliance Report """ status = ComplianceReportWorkflowStateSerializer(required=False) type = SlugRelatedField(slug_field='the_type', read_only=True) compliance_period = SlugRelatedField(slug_field='description', read_only=True) organization = OrganizationMinSerializer(read_only=True) schedule_a = ScheduleADetailSerializer(allow_null=True, required=False) schedule_b = ScheduleBDetailSerializer(allow_null=True, required=False) schedule_c = ScheduleCDetailSerializer(allow_null=True, required=False) schedule_d = ScheduleDDetailSerializer(allow_null=True, required=False) summary = ScheduleSummaryDetailSerializer(allow_null=True, required=False) actions = serializers.SerializerMethodField() actor = serializers.SerializerMethodField() strip_summary = False disregard_status = False def get_actor(self, obj): return ComplianceReportPermissions.get_relationship( obj, self.context['request'].user).value def get_actions(self, obj): relationship = ComplianceReportPermissions.get_relationship( obj, self.context['request'].user) return ComplianceReportPermissions.get_available_actions( obj, relationship) def update(self, instance, validated_data): request = self.context.get('request') if instance.read_only and not self.disregard_status and not request.user.organization.id == 1: raise PermissionDenied('Cannot modify this compliance report') if 'status' in validated_data: status_data = validated_data.pop('status') can_change = ComplianceReportPermissions.user_can_change_status( request.user, instance, new_fuel_supplier_status=status_data['fuel_supplier_status']. status if 'fuel_supplier_status' in status_data else None, new_analyst_status=status_data['analyst_status'].status if 'analyst_status' in status_data else None, new_director_status=status_data['director_status'].status if 'director_status' in status_data else None, new_manager_status=status_data['manager_status'].status if 'manager_status' in status_data else None) if not can_change: raise PermissionDenied('Invalid status change') if 'fuel_supplier_status' in status_data: instance.status.fuel_supplier_status = status_data[ 'fuel_supplier_status'] if 'analyst_status' in status_data: instance.status.analyst_status = status_data['analyst_status'] if 'manager_status' in status_data: instance.status.manager_status = status_data['manager_status'] if 'director_status' in status_data: instance.status.director_status = status_data[ 'director_status'] instance.status.save() if 'schedule_d' in validated_data: schedule_d_data = validated_data.pop('schedule_d') if instance.schedule_d: ScheduleDSheetInput.objects.filter( sheet__schedule=instance.schedule_d).delete() ScheduleDSheetOutput.objects.filter( sheet__schedule=instance.schedule_d).delete() ScheduleDSheet.objects.filter( schedule=instance.schedule_d).delete() ScheduleD.objects.filter(id=instance.schedule_d.id).delete() sheets_data = schedule_d_data.pop('sheets') schedule_d = ScheduleD.objects.create(**schedule_d_data, compliance_report=instance) instance.schedule_d = schedule_d for sheet_data in sheets_data: inputs_data = sheet_data.pop('inputs') outputs_data = sheet_data.pop('outputs') sheet = ScheduleDSheet.objects.create(**sheet_data, schedule=schedule_d) for input_data in inputs_data: input = ScheduleDSheetInput.objects.create(**input_data, sheet=sheet) sheet.inputs.add(input) sheet.save() for output_data in outputs_data: output = ScheduleDSheetOutput.objects.create(**output_data, sheet=sheet) sheet.outputs.add(output) sheet.save() schedule_d.sheets.add(sheet) schedule_d.save() instance.save() if 'schedule_c' in validated_data: schedule_c_data = validated_data.pop('schedule_c') if instance.schedule_c: ScheduleCRecord.objects.filter( schedule=instance.schedule_c).delete() ScheduleC.objects.filter(id=instance.schedule_c.id).delete() if 'records' in schedule_c_data: records_data = schedule_c_data.pop('records') schedule_c = ScheduleC.objects.create( **schedule_c_data, compliance_report=instance) instance.schedule_c = schedule_c for record_data in records_data: record = ScheduleCRecord.objects.create( **record_data, schedule=schedule_c) schedule_c.records.add(record) schedule_c.save() instance.save() if 'schedule_b' in validated_data: schedule_b_data = validated_data.pop('schedule_b') if instance.schedule_b: ScheduleBRecord.objects.filter( schedule=instance.schedule_b).delete() ScheduleB.objects.filter(id=instance.schedule_b.id).delete() if 'records' in schedule_b_data: records_data = schedule_b_data.pop('records') schedule_b = ScheduleB.objects.create( **schedule_b_data, compliance_report=instance) instance.schedule_b = schedule_b for record_data in records_data: record = ScheduleBRecord.objects.create( **record_data, schedule=schedule_b) schedule_b.records.add(record) schedule_b.save() instance.save() if 'schedule_a' in validated_data: schedule_a_data = validated_data.pop('schedule_a') if instance.schedule_a: ScheduleARecord.objects.filter( schedule=instance.schedule_a).delete() ScheduleA.objects.filter(id=instance.schedule_a.id).delete() if 'records' in schedule_a_data: records_data = schedule_a_data.pop('records') schedule_a = ScheduleA.objects.create( **schedule_a_data, compliance_report=instance) instance.schedule_a = schedule_a for record_data in records_data: record = ScheduleARecord.objects.create( **record_data, schedule=schedule_a) schedule_a.records.add(record) schedule_a.save() instance.save() if 'summary' in validated_data and not self.strip_summary: summary_data = validated_data.pop('summary') if instance.summary: ScheduleSummary.objects.filter(id=instance.summary.id).delete() summary = ScheduleSummary.objects.create( **summary_data, compliance_report=instance) instance.summary = summary instance.save() if instance.status.fuel_supplier_status.status in [ 'Submitted' ] and not instance.has_snapshot: # Create a snapshot request = self.context.get('request') snap = dict( ComplianceReportDetailSerializer(instance, context=self.context).data) snap['version'] = 1 # to track deserialization version snap['timestamp'] = datetime.now() ComplianceReportSnapshot.objects.filter( compliance_report=instance).delete() ComplianceReportSnapshot.objects.create( compliance_report=instance, create_user=request.user, create_timestamp=datetime.now(), snapshot=snap) instance.update_user = request.user instance.save() # all other fields are read-only return instance class Meta: model = ComplianceReport fields = ('status', 'type', 'compliance_period', 'organization', 'schedule_a', 'schedule_b', 'schedule_c', 'schedule_d', 'summary', 'read_only', 'has_snapshot', 'actions', 'actor') read_only_fields = ('compliance_period', 'read_only', 'has_snapshot', 'organization', 'actions', 'actor')
class ComplianceReportDetailSerializer(serializers.ModelSerializer): """ Detail Serializer for the Compliance Report """ status = ComplianceReportWorkflowStateSerializer(read_only=True) type = ComplianceReportTypeSerializer(read_only=True) organization = OrganizationMinSerializer(read_only=True) compliance_period = CompliancePeriodSerializer(read_only=True) schedule_a = ScheduleADetailSerializer(read_only=True) schedule_b = ScheduleBDetailSerializer(read_only=True) schedule_c = ScheduleCDetailSerializer(read_only=True) schedule_d = ScheduleDDetailSerializer(read_only=True) actions = serializers.SerializerMethodField() actor = serializers.SerializerMethodField() summary = serializers.SerializerMethodField() history = serializers.SerializerMethodField() def get_actor(self, obj): return ComplianceReportPermissions.get_relationship( obj, self.context['request'].user).value def get_actions(self, obj): relationship = ComplianceReportPermissions.get_relationship( obj, self.context['request'].user) return ComplianceReportPermissions.get_available_actions( obj, relationship) def get_summary(self, obj): total_petroleum_diesel = Decimal(0) total_petroleum_gasoline = Decimal(0) total_renewable_diesel = Decimal(0) total_renewable_gasoline = Decimal(0) total_credits = Decimal(0) total_debits = Decimal(0) net_gasoline_class_transferred = Decimal(0) net_diesel_class_transferred = Decimal(0) lines = {} if obj.summary is not None: lines[ '6'] = obj.summary.gasoline_class_retained if obj.summary.gasoline_class_retained is not None else Decimal( 0) lines[ '8'] = obj.summary.gasoline_class_deferred if obj.summary.gasoline_class_deferred is not None else Decimal( 0) lines[ '17'] = obj.summary.diesel_class_retained if obj.summary.diesel_class_retained is not None else Decimal( 0) lines[ '19'] = obj.summary.diesel_class_deferred if obj.summary.diesel_class_deferred is not None else Decimal( 0) lines[ '26'] = obj.summary.credits_offset if obj.summary.credits_offset is not None else Decimal( 0) else: lines['6'] = Decimal(0) lines['8'] = Decimal(0) lines['17'] = Decimal(0) lines['19'] = Decimal(0) lines['26'] = Decimal(0) if obj.schedule_a: net_gasoline_class_transferred += obj.schedule_a.net_gasoline_class_transferred net_diesel_class_transferred += obj.schedule_a.net_diesel_class_transferred lines['5'] = net_gasoline_class_transferred lines['16'] = net_diesel_class_transferred if obj.schedule_b: total_petroleum_diesel += obj.schedule_b.total_petroleum_diesel total_petroleum_gasoline += obj.schedule_b.total_petroleum_gasoline total_renewable_diesel += obj.schedule_b.total_renewable_diesel total_renewable_gasoline += obj.schedule_b.total_renewable_gasoline total_credits += obj.schedule_b.total_credits total_debits += obj.schedule_b.total_debits if obj.schedule_c: total_petroleum_diesel += obj.schedule_c.total_petroleum_diesel lines['1'] = total_petroleum_gasoline lines['2'] = total_renewable_gasoline lines['3'] = lines['1'] + lines['2'] lines['4'] = (lines['3'] * Decimal('0.05')).quantize( Decimal('1.'), rounding=ROUND_HALF_UP) # hardcoded 5% renewable requirement lines['7'] = Decimal(0) lines['9'] = Decimal(0) lines['10'] = lines['2'] + lines['5'] - lines['6'] + lines[ '7'] + lines['8'] - lines['9'] lines['11'] = ((lines['4'] - lines['10']) * Decimal('0.30')).max( Decimal(0)).quantize(Decimal('.01'), rounding=ROUND_HALF_UP) lines['12'] = total_petroleum_diesel lines['13'] = total_renewable_diesel lines['14'] = lines['12'] + lines['13'] lines['15'] = (lines['14'] * Decimal('0.04')).quantize( Decimal('1.'), rounding=ROUND_HALF_UP) # hardcoded 4% renewable requirement lines['18'] = Decimal(0) lines['20'] = Decimal(0) lines['21'] = lines['13'] + lines['16'] - lines['17'] + lines[ '18'] + lines['19'] - lines['20'] lines['22'] = ((lines['15'] - lines['21']) * Decimal('0.45')).max( Decimal(0)).quantize(Decimal('.01'), rounding=ROUND_HALF_UP) lines['23'] = total_credits lines['24'] = total_debits lines['25'] = lines['23'] - lines['24'] lines['27'] = lines['25'] + lines['26'] lines['28'] = (lines['27'] * Decimal('-200.00')).max(Decimal(0)) total_payable = lines['11'] + lines['22'] + lines['28'] synthetic_totals = { "total_petroleum_diesel": total_petroleum_diesel, "total_petroleum_gasoline": total_petroleum_gasoline, "total_renewable_diesel": total_renewable_diesel, "total_renewable_gasoline": total_renewable_gasoline, "net_diesel_class_transferred": net_diesel_class_transferred, "net_gasoline_class_transferred": net_gasoline_class_transferred, "lines": lines, "total_payable": total_payable } if obj.summary is not None: ser = ScheduleSummaryDetailSerializer(obj.summary) data = ser.data synthetic_totals = {**data, **synthetic_totals} return synthetic_totals def get_history(self, obj): """ Returns all the previous status changes for the compliance report """ user = self.context[ 'request'].user if 'request' in self.context else None if user and user.is_government_user: from .ComplianceReportHistory import ComplianceReportHistorySerializer history = obj.get_history(["Submitted"]) serializer = ComplianceReportHistorySerializer(history, many=True) return serializer.data else: return None class Meta: model = ComplianceReport fields = [ 'id', 'status', 'type', 'organization', 'compliance_period', 'schedule_a', 'schedule_b', 'schedule_c', 'schedule_d', 'summary', 'read_only', 'history', 'has_snapshot', 'actions', 'actor' ]
class ComplianceReportDetailSerializer(serializers.ModelSerializer): status = ComplianceReportStatusSerializer(read_only=True) type = ComplianceReportTypeSerializer(read_only=True) organization = OrganizationMinSerializer(read_only=True) compliance_period = CompliancePeriodSerializer(read_only=True) schedule_a = ScheduleADetailSerializer(read_only=True) schedule_b = ScheduleBDetailSerializer(read_only=True) schedule_c = ScheduleCDetailSerializer(read_only=True) summary = serializers.SerializerMethodField() def get_summary(self, obj): total_petroleum_diesel = 0 total_petroleum_gasoline = 0 total_renewable_diesel = 0 total_renewable_gasoline = 0 schedule_b_records = ScheduleBRecord.objects.filter( schedule=obj.schedule_b) for record in schedule_b_records: percentage = 100 if record.fuel_code is not None and \ record.fuel_code.renewable_percentage and \ record.fuel_code.renewable_percentage > 0: percentage = record.fuel_code.renewable_percentage if record.fuel_type.name in [ "Biodiesel", "HDRD", "Renewable diesel" ]: total_renewable_diesel += record.quantity * percentage / 100 elif record.fuel_type.name in ["Ethanol", "Renewable gasoline"]: total_renewable_gasoline += record.quantity * percentage / 100 elif record.fuel_type.name == "Petroleum-based diesel": total_petroleum_diesel += record.quantity elif record.fuel_type.name == "Petroleum-based gasoline": total_petroleum_gasoline += record.quantity schedule_c_records = ScheduleCRecord.objects.filter( schedule=obj.schedule_c) for record in schedule_c_records: if record.fuel_type.name == "Petroleum-based diesel" and \ record.expected_use.description == "Heating Oil": total_petroleum_diesel += record.quantity return { "total_petroleum_diesel": total_petroleum_diesel, "total_petroleum_gasoline": total_petroleum_gasoline, "total_renewable_diesel": total_renewable_diesel, "total_renewable_gasoline": total_renewable_gasoline } class Meta: model = ComplianceReport fields = [ 'id', 'status', 'type', 'organization', 'compliance_period', 'schedule_a', 'schedule_b', 'schedule_c', 'summary' ]
class ComplianceReportUpdateSerializer(serializers.ModelSerializer): status = SlugRelatedField( slug_field='status', queryset=ComplianceReportStatus.objects.filter(status__in=['Draft'])) type = SlugRelatedField(slug_field='the_type', read_only=True) compliance_period = SlugRelatedField(slug_field='description', read_only=True) organization = OrganizationMinSerializer(read_only=True) schedule_a = ScheduleADetailSerializer(allow_null=True, required=False) schedule_b = ScheduleBDetailSerializer(allow_null=True, required=False) schedule_c = ScheduleCDetailSerializer(allow_null=True, required=False) def update(self, instance, validated_data): if 'schedule_c' in validated_data: schedule_c_data = validated_data.pop('schedule_c') if instance.schedule_c: ScheduleCRecord.objects.filter( schedule=instance.schedule_c).delete() instance.schedule_c.delete() if 'records' in schedule_c_data: records_data = schedule_c_data.pop('records') schedule_c = ScheduleC.objects.create( **schedule_c_data, compliance_report=instance) instance.schedule_c = schedule_c for record_data in records_data: record = ScheduleCRecord.objects.create( **record_data, schedule=schedule_c) schedule_c.records.add(record) schedule_c.save() instance.save() if 'schedule_b' in validated_data: schedule_b_data = validated_data.pop('schedule_b') if instance.schedule_b: ScheduleBRecord.objects.filter( schedule=instance.schedule_b).delete() instance.schedule_b.delete() if 'records' in schedule_b_data: records_data = schedule_b_data.pop('records') schedule_b = ScheduleB.objects.create( **schedule_b_data, compliance_report=instance) instance.schedule_b = schedule_b for record_data in records_data: record = ScheduleBRecord.objects.create( **record_data, schedule=schedule_b) schedule_b.records.add(record) schedule_b.save() instance.save() if 'schedule_a' in validated_data: schedule_a_data = validated_data.pop('schedule_a') if instance.schedule_a: ScheduleARecord.objects.filter( schedule=instance.schedule_a).delete() instance.schedule_a.delete() if 'records' in schedule_a_data: records_data = schedule_a_data.pop('records') schedule_a = ScheduleA.objects.create( **schedule_a_data, compliance_report=instance) instance.schedule_a = schedule_a for record_data in records_data: record = ScheduleARecord.objects.create( **record_data, schedule=schedule_a) schedule_a.records.add(record) schedule_a.save() instance.save() # all other fields are read-only return instance class Meta: model = ComplianceReport fields = ('status', 'type', 'compliance_period', 'organization', 'schedule_a', 'schedule_b', 'schedule_c')