def update(self, request, pk): """ Update a taxlot --- parameters: - name: cycle_id description: The cycle id for filtering the taxlot view required: true paramType: query """ data = request.data cycle_pk = request.query_params.get('cycle_id', None) if not cycle_pk: return JsonResponse({ 'status': 'error', 'message': 'Must pass in cycle_id as query parameter' }) result = self._get_taxlot_view(pk, cycle_pk) if result.get('status', None) != 'error': taxlot_view = result.pop('taxlot_view') taxlot_state_data = TaxLotStateSerializer(taxlot_view.state).data new_taxlot_state_data = data['state'] changed = True for key, val in new_taxlot_state_data.iteritems(): if val == '': new_taxlot_state_data[key] = None changed_fields = get_changed_fields(taxlot_state_data, new_taxlot_state_data) if not changed_fields: changed = False if not changed: result.update({ 'status': 'error', 'message': 'Nothing to update' }) status_code = 422 # status.HTTP_422_UNPROCESSABLE_ENTITY else: log = TaxLotAuditLog.objects.select_related().filter( state=taxlot_view.state).order_by('-id').first() if 'extra_data' in new_taxlot_state_data.keys(): taxlot_state_data['extra_data'].update( new_taxlot_state_data.pop('extra_data')) taxlot_state_data.update(new_taxlot_state_data) if log.name == 'Import Creation': # Add new state taxlot_state_data.pop('id') new_taxlot_state_serializer = TaxLotStateSerializer( data=taxlot_state_data) if new_taxlot_state_serializer.is_valid(): new_state = new_taxlot_state_serializer.save() taxlot_view.state = new_state taxlot_view.save() TaxLotAuditLog.objects.create( organization=log.organization, parent1=log, parent2=None, parent_state1=log.state, parent_state2=None, state=new_state, name='Manual Edit', description=None, import_filename=log.import_filename, record_type=AUDIT_USER_EDIT) result.update({ 'state': new_taxlot_state_serializer.validated_data }) # Removing organization key AND import_file key because they're not JSON-serializable # TODO find better solution result['state'].pop('organization') result['state'].pop('import_file') status_code = status.HTTP_201_CREATED else: result.update({ 'status': 'error', 'message': 'Invalid Data' }) status_code = 422 # status.HTTP_422_UNPROCESSABLE_ENTITY elif log.name in [ 'Manual Edit', 'Manual Match', 'System Match', 'Merge current state in migration' ]: # Override previous edit state or merge state state = taxlot_view.state for key, value in new_taxlot_state_data.iteritems(): setattr(state, key, value) state.save() result.update({'state': TaxLotStateSerializer(state).data}) # Removing organization key AND import_file key because they're not JSON-serializable # TODO find better solution result['state'].pop('organization') result['state'].pop('import_file') status_code = status.HTTP_201_CREATED else: result = { 'status': 'error', 'message': 'Unrecognized audit log name: ' + log.name } status_code = 422 return JsonResponse(result, status=status_code) else: status_code = status.HTTP_404_NOT_FOUND return JsonResponse(result, status=status_code)
def update(self, request, pk): """ Update a taxlot --- parameters: - name: organization_id description: The organization_id for this user's organization required: true paramType: query """ data = request.data result = self._get_taxlot_view(pk) if result.get('status', 'error') != 'error': taxlot_view = result.pop('taxlot_view') taxlot_state_data = TaxLotStateSerializer(taxlot_view.state).data # get the taxlot state information from the request new_taxlot_state_data = data['state'] # set empty strings to None for key, val in new_taxlot_state_data.iteritems(): if val == '': new_taxlot_state_data[key] = None changed_fields = get_changed_fields(taxlot_state_data, new_taxlot_state_data) if not changed_fields: result.update({ 'status': 'success', 'message': 'Records are identical' }) return JsonResponse(result, status=status.HTTP_204_NO_CONTENT) else: # Not sure why we are going through the pain of logging this all right now... need to # reevaluate this. log = TaxLotAuditLog.objects.select_related().filter( state=taxlot_view.state).order_by('-id').first() if 'extra_data' in new_taxlot_state_data.keys(): taxlot_state_data['extra_data'].update( new_taxlot_state_data.pop('extra_data')) taxlot_state_data.update(new_taxlot_state_data) if log.name == 'Import Creation': # Add new state by removing the existing ID. taxlot_state_data.pop('id') new_taxlot_state_serializer = TaxLotStateSerializer( data=taxlot_state_data) if new_taxlot_state_serializer.is_valid(): # create the new property state, and perform an initial save / moving relationships new_state = new_taxlot_state_serializer.save() # then assign this state to the property view and save the whole view taxlot_view.state = new_state taxlot_view.save() TaxLotAuditLog.objects.create( organization=log.organization, parent1=log, parent2=None, parent_state1=log.state, parent_state2=None, state=new_state, name='Manual Edit', description=None, import_filename=log.import_filename, record_type=AUDIT_USER_EDIT) result.update( {'state': new_taxlot_state_serializer.data}) return JsonResponse(result, status=status.HTTP_200_OK) else: result.update({ 'status': 'error', 'message': 'Invalid update data with errors: {}'.format( new_taxlot_state_serializer.errors) }) return JsonResponse( result, status=status.HTTP_422_UNPROCESSABLE_ENTITY) elif log.name in [ 'Manual Edit', 'Manual Match', 'System Match', 'Merge current state in migration' ]: # Convert this to using the serializer to save the data. This will override the previous values # in the state object. # Note: We should be able to use partial update here and pass in the changed fields instead of the # entire state_data. updated_taxlot_state_serializer = TaxLotStateSerializer( taxlot_view.state, data=taxlot_state_data) if updated_taxlot_state_serializer.is_valid(): # create the new property state, and perform an initial save / moving relationships updated_taxlot_state_serializer.save() result.update( {'state': updated_taxlot_state_serializer.data}) return JsonResponse(result, status=status.HTTP_200_OK) else: result.update({ 'status': 'error', 'message': 'Invalid update data with errors: {}'.format( updated_taxlot_state_serializer.errors) }) return JsonResponse( result, status=status.HTTP_422_UNPROCESSABLE_ENTITY) else: result = { 'status': 'error', 'message': 'Unrecognized audit log name: ' + log.name } return JsonResponse(result, status=status.HTTP_204_NO_CONTENT) # save the tax lot view, even if it hasn't changed so that the datetime gets updated on the taxlot. # Uhm, does this ever get called? There are a bunch of returns in the code above. taxlot_view.save() else: return JsonResponse(result, status=status.HTTP_404_NOT_FOUND) return JsonResponse(result, status=status.HTTP_404_NOT_FOUND)
def update(self, request, pk): """ Update a taxlot and run the updated record through a match and merge round within it's current Cycle. --- parameters: - name: organization_id description: The organization_id for this user's organization required: true paramType: query """ data = request.data result = self._get_taxlot_view(pk) if result.get('status', 'error') != 'error': taxlot_view = result.pop('taxlot_view') taxlot_state_data = TaxLotStateSerializer(taxlot_view.state).data # get the taxlot state information from the request new_taxlot_state_data = data['state'] # set empty strings to None for key, val in new_taxlot_state_data.items(): if val == '': new_taxlot_state_data[key] = None changed_fields, previous_data = get_changed_fields( taxlot_state_data, new_taxlot_state_data) if not changed_fields: result.update({ 'status': 'success', 'message': 'Records are identical' }) return JsonResponse(result, status=status.HTTP_204_NO_CONTENT) else: # Not sure why we are going through the pain of logging this all right now... need to # reevaluate this. log = TaxLotAuditLog.objects.select_related().filter( state=taxlot_view.state).order_by('-id').first() # if checks above pass, create an exact copy of the current state for historical purposes if log.name == 'Import Creation': # Add new state by removing the existing ID. taxlot_state_data.pop('id') # Remove the import_file_id for the first edit of a new record # If the import file has been deleted and this value remains the serializer won't be valid taxlot_state_data.pop('import_file') new_taxlot_state_serializer = TaxLotStateSerializer( data=taxlot_state_data) if new_taxlot_state_serializer.is_valid(): # create the new property state, and perform an initial save / moving relationships new_state = new_taxlot_state_serializer.save() # then assign this state to the property view and save the whole view taxlot_view.state = new_state taxlot_view.save() TaxLotAuditLog.objects.create( organization=log.organization, parent1=log, parent2=None, parent_state1=log.state, parent_state2=None, state=new_state, name='Manual Edit', description=None, import_filename=log.import_filename, record_type=AUDIT_USER_EDIT) result.update( {'state': new_taxlot_state_serializer.data}) # save the property view so that the datetime gets updated on the property. taxlot_view.save() else: result.update({ 'status': 'error', 'message': 'Invalid update data with errors: {}'.format( new_taxlot_state_serializer.errors) }) return JsonResponse( result, status=status.HTTP_422_UNPROCESSABLE_ENTITY) # redo assignment of this variable in case this was an initial edit taxlot_state_data = TaxLotStateSerializer( taxlot_view.state).data if 'extra_data' in new_taxlot_state_data: taxlot_state_data['extra_data'].update( new_taxlot_state_data['extra_data']) taxlot_state_data.update({ k: v for k, v in new_taxlot_state_data.items() if k != 'extra_data' }) log = TaxLotAuditLog.objects.select_related().filter( state=taxlot_view.state).order_by('-id').first() if log.name in [ 'Manual Edit', 'Manual Match', 'System Match', 'Merge current state in migration' ]: # Convert this to using the serializer to save the data. This will override the # previous values in the state object. # Note: We should be able to use partial update here and pass in the changed # fields instead of the entire state_data. updated_taxlot_state_serializer = TaxLotStateSerializer( taxlot_view.state, data=taxlot_state_data) if updated_taxlot_state_serializer.is_valid(): # create the new property state, and perform an initial save / moving # relationships updated_taxlot_state_serializer.save() result.update( {'state': updated_taxlot_state_serializer.data}) # save the property view so that the datetime gets updated on the property. taxlot_view.save() Note.create_from_edit(request.user.id, taxlot_view, new_taxlot_state_data, previous_data) merge_count, link_count, view_id = match_merge_link( taxlot_view.id, 'TaxLotState') result.update({ 'view_id': view_id, 'match_merged_count': merge_count, 'match_link_count': link_count, }) return JsonResponse(result, status=status.HTTP_200_OK) else: result.update({ 'status': 'error', 'message': 'Invalid update data with errors: {}'.format( updated_taxlot_state_serializer.errors) }) return JsonResponse( result, status=status.HTTP_422_UNPROCESSABLE_ENTITY) else: result = { 'status': 'error', 'message': 'Unrecognized audit log name: ' + log.name } return JsonResponse(result, status=status.HTTP_204_NO_CONTENT) else: return JsonResponse(result, status=status.HTTP_404_NOT_FOUND)
def update(self, request, pk=None): """ Update a property and run the updated record through a match and merge round within it's current Cycle. - looks up the property view - casts it as a PropertyState - builds a hash with all the same keys as the original property state - checks if any fields have changed - if nothing has changed, return 422 - Really? Not sure how I feel about that one, it *is* processable - get the property audit log for this property state - if the new property state has extra_data, the original extra_data is update'd - and then whoa stuff about the audit log? - I'm going to assume 'Import Creation' is the key I'm looking for - create a serializer for the new property state - if it's valid, save this new serialized data to the db - assign it to the original property view and save the property view - create a new property audit log for this change - return a 200 if created --- parameters: - name: organization_id description: The organization_id for this user's organization required: true paramType: query """ data = request.data result = self._get_property_view(pk) if result.get('status', None) != 'error': property_view = result.pop('property_view') property_state_data = PropertyStateSerializer( property_view.state).data # get the property state information from the request new_property_state_data = data['state'] # set empty strings to None for key, val in new_property_state_data.items(): if val == '': new_property_state_data[key] = None changed_fields = get_changed_fields(property_state_data, new_property_state_data) if not changed_fields: result.update({ 'status': 'success', 'message': 'Records are identical' }) return JsonResponse(result, status=status.HTTP_204_NO_CONTENT) else: # Not sure why we are going through the pain of logging this all right now... need to # reevaluate this. log = PropertyAuditLog.objects.select_related().filter( state=property_view.state).order_by('-id').first() if 'extra_data' in new_property_state_data: property_state_data['extra_data'].update( new_property_state_data.pop('extra_data')) property_state_data.update(new_property_state_data) if log.name == 'Import Creation': # Add new state by removing the existing ID. property_state_data.pop('id') new_property_state_serializer = PropertyStateSerializer( data=property_state_data) if new_property_state_serializer.is_valid(): # create the new property state, and perform an initial save / moving relationships new_state = new_property_state_serializer.save() # Since we are creating a new relationship when we are manually editing the Properties, then # we need to move the relationships over to the new manually edited record. new_state = self._move_relationships( property_view.state, new_state) new_state.save() # then assign this state to the property view and save the whole view property_view.state = new_state property_view.save() PropertyAuditLog.objects.create( organization=log.organization, parent1=log, parent2=None, parent_state1=log.state, parent_state2=None, state=new_state, name='Manual Edit', description=None, import_filename=log.import_filename, record_type=AUDIT_USER_EDIT) result.update( {'state': new_property_state_serializer.data}) # save the property view so that the datetime gets updated on the property. property_view.save() count, view_id = match_merge_in_cycle( property_view.id, 'PropertyState') if view_id is not None: result.update({ 'view_id': view_id, 'match_merged_count': count, }) return JsonResponse(result, encoder=PintJSONEncoder, status=status.HTTP_200_OK) else: result.update({ 'status': 'error', 'message': 'Invalid update data with errors: {}'.format( new_property_state_serializer.errors) }) return JsonResponse( result, encoder=PintJSONEncoder, status=status.HTTP_422_UNPROCESSABLE_ENTITY) elif log.name in [ 'Manual Edit', 'Manual Match', 'System Match', 'Merge current state in migration' ]: # Convert this to using the serializer to save the data. This will override the previous values # in the state object. # Note: We should be able to use partial update here and pass in the changed fields instead of the # entire state_data. updated_property_state_serializer = PropertyStateSerializer( property_view.state, data=property_state_data) if updated_property_state_serializer.is_valid(): # create the new property state, and perform an initial save / moving # relationships updated_property_state_serializer.save() result.update( {'state': updated_property_state_serializer.data}) # save the property view so that the datetime gets updated on the property. property_view.save() count, view_id = match_merge_in_cycle( property_view.id, 'PropertyState') if view_id is not None: result.update({ 'view_id': view_id, 'match_merged_count': count, }) return JsonResponse(result, encoder=PintJSONEncoder, status=status.HTTP_200_OK) else: result.update({ 'status': 'error', 'message': 'Invalid update data with errors: {}'.format( updated_property_state_serializer.errors) }) return JsonResponse( result, encoder=PintJSONEncoder, status=status.HTTP_422_UNPROCESSABLE_ENTITY) else: result = { 'status': 'error', 'message': 'Unrecognized audit log name: ' + log.name } return JsonResponse( result, status=status.HTTP_422_UNPROCESSABLE_ENTITY) else: return JsonResponse(result, status=status.HTTP_404_NOT_FOUND)