mirror of
https://github.com/lemeow125/Borrowing-TrackerBackend.git
synced 2025-04-27 10:11:24 +08:00
Improved serializer for transaction and added available equipment viewset
This commit is contained in:
parent
94ba018c9e
commit
d0ca68149a
6 changed files with 167 additions and 47 deletions
|
@ -106,57 +106,106 @@ class TransactionSerializer(serializers.HyperlinkedModelSerializer):
|
|||
raise serializers.ValidationError(
|
||||
f"Cannot add Equipment ID:{equipment.id}. It is still part of a non-finalized transaction")
|
||||
|
||||
return super().create(validated_data)
|
||||
# Create the transaction if there are no issues
|
||||
transaction = super().create(validated_data)
|
||||
|
||||
# Get the equipments from the newly created transaction
|
||||
equipments = transaction.equipments.all()
|
||||
|
||||
# Iterate through each of those equipment instances and change their status field to "Pending"
|
||||
# This updates the status field of all equipment instances in a single query
|
||||
EquipmentInstance.objects.filter(
|
||||
id__in=[equipment.id for equipment in equipments]).update(status='Pending')
|
||||
|
||||
return transaction
|
||||
|
||||
def update(self, instance, validated_data):
|
||||
user = self.context['request'].user
|
||||
|
||||
# If user is not a teacher or a technician, forbid them from changing the status of a transaction
|
||||
if not user.is_teacher and not user.is_technician and 'transaction_status' in validated_data and validated_data['transaction_status'] != instance.transaction_status:
|
||||
# User Validation
|
||||
|
||||
# If user is not a teacher or a technician (ie a student), forbid them from changing the status of a transaction
|
||||
if not user.is_teacher and not user.is_technician and 'transaction_status' in validated_data and validated_data.get('transaction_status') != instance.transaction_status:
|
||||
raise serializers.ValidationError(
|
||||
"You are not a teacher or technician. You do not have permission to change the status of transactions"
|
||||
)
|
||||
|
||||
# If user is not a teacher, forbid them from changing the status of a transaction
|
||||
if not user.is_teacher and 'transaction_status' in validated_data and validated_data['transaction_status'] != instance.transaction_status:
|
||||
# If the user is a teacher but is not assigned to the current transaction, forbid them from changing anything in the transaction
|
||||
if user.is_teacher and instance.teacher != user:
|
||||
raise serializers.ValidationError(
|
||||
"You do not have permission to change the status of a transaction"
|
||||
"You are not the assigned teacher for this transaction"
|
||||
)
|
||||
|
||||
# If the user is a teacher and is updating a transaction with values other than Approved or Rejected, forbid them from doing so (Only technicians can update to other statuses)
|
||||
if user.is_teacher and not (validated_data.get('transaction_status') == 'Rejected' or validated_data.get('transaction_status') == 'Approved'):
|
||||
raise serializers.ValidationError(
|
||||
"Teachers can only mark assigned transactions as Approved or Rejected. Please consult with a Technician should you wish to process this request"
|
||||
)
|
||||
|
||||
# Equipment Instances Validation
|
||||
# Do not allow changes to equipments on created transactions
|
||||
if 'equipments' in validated_data and instance.equipments != validated_data['equipments']:
|
||||
if 'equipments' in validated_data:
|
||||
raise serializers.ValidationError(
|
||||
"You cannot change the equipments of an already created transaction"
|
||||
)
|
||||
|
||||
# For already finalized/done transactions (Rejected or Finalized ones)
|
||||
# Do not allow any changes to already finalized transactions
|
||||
if instance.transaction_status in ['Rejected', 'Finalized']:
|
||||
raise serializers.ValidationError(
|
||||
"Unable to update rejected or finalized transaction. Please create a new one"
|
||||
)
|
||||
|
||||
# Transaction Status Validation
|
||||
# Check if the update involves the transaction status
|
||||
if 'transaction_status' in validated_data:
|
||||
|
||||
# For Pending transactions
|
||||
# For already finalized/done transactions (Rejected or Finalized ones)
|
||||
# Do not allow any changes to already finalized transactions
|
||||
if instance.transaction_status in ['Rejected', 'Finalized']:
|
||||
raise serializers.ValidationError(
|
||||
"Unable to update rejected or finalized transaction. Please create a new one"
|
||||
)
|
||||
|
||||
# For Pending Approval transactions
|
||||
# If not changing to Approved or Rejected, throw an error
|
||||
if instance.transaction_status == "Pending" and (validated_data['transaction_status'] != "Approved" or validated_data['transaction_status'] != "Rejected"):
|
||||
if instance.transaction_status == "Pending Approval" and not (validated_data.get('transaction_status') == "Approved" or validated_data.get('transaction_status') == "Rejected"):
|
||||
raise serializers.ValidationError(
|
||||
"A pending transaction can only change to Approved or Rejected"
|
||||
)
|
||||
|
||||
# If a transaction goes from Pending Approval to Rejected, reset the status of related equipment instances so that they can be included in new transactions
|
||||
if instance.transaction_status == "Pending Approval" and validated_data.get('transaction_status') == "Rejected":
|
||||
equipments = instance.equipments.all()
|
||||
# Iterate through each of those equipment instances and change their status field to "Available"
|
||||
# This updates the status field of all equipment instances in a single query
|
||||
EquipmentInstance.objects.filter(
|
||||
id__in=[equipment.id for equipment in equipments]).update(status='Available')
|
||||
return super().update(instance, validated_data)
|
||||
|
||||
# For Approved transactions,
|
||||
# If not changing to Borrowed or Cancelled, throw an error
|
||||
# Already approved transactions can only be moved to Borrowed or Cancelled
|
||||
if instance.transaction_status == "Approved" and (validated_data['transaction_status'] != "Borrowed" or validated_data != "Cancelled"):
|
||||
if instance.transaction_status == "Approved" and not (validated_data.get('transaction_status') == "Borrowed" or validated_data.get('transaction_status') == "Cancelled"):
|
||||
raise serializers.ValidationError(
|
||||
"An already approved transaction can only changed to Borrowed (On borrow) or Cancelled"
|
||||
"An already approved transaction can only changed to Borrowed or Cancelled"
|
||||
)
|
||||
|
||||
# If the transaction somehow gets Cancelled after being Approved, label the selected equipment's statuses as Available again
|
||||
if instance.transaction_status == "Approved" and validated_data.get('transaction_status') == "Cancelled":
|
||||
equipments = instance.equipments.all()
|
||||
# Iterate through each of those equipment instances and change their status field to "Available"
|
||||
# This updates the status field of all equipment instances in a single query
|
||||
EquipmentInstance.objects.filter(
|
||||
id__in=[equipment.id for equipment in equipments]).update(status='Available')
|
||||
return super().update(instance, validated_data)
|
||||
|
||||
# If there are no issues and a transaction changes from Approved to Borrowed, label the selected equipment's statuses as Borrowed
|
||||
if instance.transaction_status == "Approved" and validated_data.get('transaction_status') == "Borrowed":
|
||||
equipments = instance.equipments.all()
|
||||
# Iterate through each of those equipment instances and change their status field to "Borrowed"
|
||||
# This updates the status field of all equipment instances in a single query
|
||||
EquipmentInstance.objects.filter(
|
||||
id__in=[equipment.id for equipment in equipments]).update(status='Borrowed')
|
||||
return super().update(instance, validated_data)
|
||||
|
||||
# For Borrowed transactions,
|
||||
# If not changing to returned, throw an error
|
||||
# Borrowed transactions that can only be changed to returned, pending checking for broken items
|
||||
if instance.transaction_status == "Borrowed" and (validated_data['transaction_status'] != "Finalized" or validated_data != "With Breakages: Pending Resolution"):
|
||||
# If not changing to Returned: Pending Checking, throw an error
|
||||
# Borrowed transactions that are Returned must be checked first upon returning (thus needing Returned: Pending Checking)
|
||||
if instance.transaction_status == "Borrowed" and not validated_data.get('transaction_status') == "Returned: Pending Checking":
|
||||
raise serializers.ValidationError(
|
||||
"A borrowed transaction can only changed to status of Finalized or With Breakages: Pending Resolution"
|
||||
)
|
||||
|
@ -164,12 +213,12 @@ class TransactionSerializer(serializers.HyperlinkedModelSerializer):
|
|||
# For Return: Pending Checking transactions,
|
||||
# If not changing to With Breakages: Pending Resolution or Finalized, throw an error
|
||||
# Returned transactions can only be finalized without any issues or be marked as with breakages
|
||||
if instance.transaction_status == "Returned: Pending Checking" and (validated_data['transaction_status'] != "Finalized" or validated_data != "With Breakages: Pending Resolution"):
|
||||
if instance.transaction_status == "Returned: Pending Checking" and not (validated_data.get('transaction_status') == "Finalized" or validated_data.get('transaction_status') == "With Breakages: Pending Resolution"):
|
||||
raise serializers.ValidationError(
|
||||
"A borrowed transaction can only changed to status of Finalized or With Breakages: Pending Resolution"
|
||||
)
|
||||
|
||||
# For transactions with pending breakage resolutions,
|
||||
# For transactions with pending breakage resolutions
|
||||
# Do not allow updating of status. It should be updated within its respective breakage report
|
||||
# If it has been resolved there, this field will automatically update to Finalized
|
||||
if instance.transaction_status == "With Breakages: Pending Resolution":
|
||||
|
@ -177,27 +226,24 @@ class TransactionSerializer(serializers.HyperlinkedModelSerializer):
|
|||
"A transaction with pending breakage resolutions must be updated or resolved in its respective breakage report"
|
||||
)
|
||||
|
||||
# If there are no issues and a transaction changes from Approved to Borrowed, label the selected equipment's statuses as Borrowed
|
||||
if instance.transaction_status == "Approved" and validated_data['transaction_status'] == "Borrowed":
|
||||
equipments = validated_data.get('equipments', [])
|
||||
for equipment in equipments:
|
||||
equipment.transaction_status = 'Borrowed'
|
||||
equipment.save()
|
||||
return super().update(validated_data)
|
||||
# If the transaction changes from Borrowed to Finalized and there are no breakages, label the selected equipment's statuses as Available again from Borrowed
|
||||
if instance.transaction_status == "Borrowed" and validated_data['transaction_status'] == "Finalized":
|
||||
equipments = validated_data.get('equipments', [])
|
||||
for equipment in equipments:
|
||||
equipment.transaction_status = 'Available'
|
||||
equipment.save()
|
||||
return super().update(validated_data)
|
||||
# If the transaction changes from Borrowed to With Breakages, we create a Breakage Report instance
|
||||
if instance.transaction_status == "Borrowed" and validated_data['transaction_status'] == "Finalized":
|
||||
BreakageReport.objects.create(
|
||||
if instance.transaction_status == "Borrowed" and validated_data.get('transaction_status') == "Finalized":
|
||||
equipments = instance.equipments.all()
|
||||
# Iterate through each of those equipment instances and change their status field to "Available"
|
||||
# This updates the status field of all equipment instances in a single query
|
||||
EquipmentInstance.objects.filter(
|
||||
id__in=[equipment.id for equipment in equipments]).update(status='Available')
|
||||
return super().update(instance, validated_data)
|
||||
|
||||
# If the transaction changes from Returned: Pending Checking to With Breakages, we create a Breakage Report instance
|
||||
if instance.transaction_status == "Returned: Pending Checking" and validated_data.get('transaction_status') == "With Breakages: Pending Resolution":
|
||||
equipments = instance.equipments.all()
|
||||
report = BreakageReport.objects.create(
|
||||
transaction=instance,
|
||||
equipments=instance.equipments.all(),
|
||||
resolved=False
|
||||
)
|
||||
report.equipments.set(equipments)
|
||||
return super().update(instance, validated_data)
|
||||
# Changing equipment status of broken items when there are breakages is handled in breakage reports
|
||||
|
||||
return super().update(instance, validated_data)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue