mirror of
https://github.com/lemeow125/Borrowing-TrackerBackend.git
synced 2024-11-16 22:09:27 +08:00
Change Working status to Available
This commit is contained in:
parent
8abf689544
commit
9e16bda918
6 changed files with 110 additions and 33 deletions
|
@ -0,0 +1,23 @@
|
|||
# Generated by Django 4.2.7 on 2023-12-16 06:53
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('equipments', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='equipmentinstance',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('Available', 'Available'), ('Broken', 'Broken'), ('Borrowed', 'Borrowed')], default='Available', max_length=20),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='historicalequipmentinstance',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('Available', 'Available'), ('Broken', 'Broken'), ('Borrowed', 'Borrowed')], default='Available', max_length=20),
|
||||
),
|
||||
]
|
|
@ -24,13 +24,13 @@ class Equipment(models.Model):
|
|||
|
||||
class EquipmentInstance(models.Model):
|
||||
EQUIPMENT_INSTANCE_STATUS_CHOICES = (
|
||||
('Working', 'Working'),
|
||||
('Available', 'Available'),
|
||||
('Broken', 'Broken'),
|
||||
('Borrowed', 'Borrowed'),
|
||||
)
|
||||
equipment = models.ForeignKey(Equipment, on_delete=models.CASCADE)
|
||||
status = models.CharField(
|
||||
max_length=20, choices=EQUIPMENT_INSTANCE_STATUS_CHOICES, default='PENDING')
|
||||
max_length=20, choices=EQUIPMENT_INSTANCE_STATUS_CHOICES, default='Available')
|
||||
remarks = models.TextField(max_length=512, null=True)
|
||||
date_added = models.DateTimeField(default=now, editable=False)
|
||||
last_updated = models.DateTimeField(auto_now=True, editable=False)
|
||||
|
@ -46,12 +46,12 @@ def create_superuser(sender, **kwargs):
|
|||
EQUIPMENT, CREATED = Equipment.objects.get_or_create(
|
||||
name="Pyrex Beaker", description="", category="Glassware")
|
||||
EQUIPMENT_INSTANCE, CREATED = EquipmentInstance.objects.get_or_create(
|
||||
equipment=EQUIPMENT, status="Working", remarks="First beaker of equipment tracker!")
|
||||
equipment=EQUIPMENT, status="Available", remarks="First beaker of equipment tracker!")
|
||||
EQUIPMENT, CREATED = Equipment.objects.get_or_create(
|
||||
name="Bunsen Burner", description="", category="Miscellaneous")
|
||||
EQUIPMENT_INSTANCE, CREATED = EquipmentInstance.objects.get_or_create(
|
||||
equipment=EQUIPMENT, status="Working", remarks="First bunsen burner of equipment tracker!")
|
||||
equipment=EQUIPMENT, status="Available", remarks="First bunsen burner of equipment tracker!")
|
||||
EQUIPMENT, CREATED = Equipment.objects.get_or_create(
|
||||
name="Microscope", description="", category="Miscellaneous")
|
||||
EQUIPMENT_INSTANCE, CREATED = EquipmentInstance.objects.get_or_create(
|
||||
equipment=EQUIPMENT, status="Working", remarks="First microscope of equipment tracker!")
|
||||
equipment=EQUIPMENT, status="Available", remarks="First microscope of equipment tracker!")
|
||||
|
|
|
@ -159,12 +159,12 @@ class EquipmentInstanceSerializer(serializers.HyperlinkedModelSerializer):
|
|||
equipments=instance, resolved=False).first()
|
||||
# If there is one
|
||||
if associated_breakage_report:
|
||||
# Check if all the equipments of the currently associated BreakageReport are "Working"
|
||||
all_working = all(
|
||||
eq.status == 'Working' for eq in associated_breakage_report.equipments.all())
|
||||
# Check if all the equipments of the currently associated BreakageReport are "Available"
|
||||
all_available = all(
|
||||
eq.status == 'Available' for eq in associated_breakage_report.equipments.all())
|
||||
|
||||
# If all the equipments are "Working", set Breakage Report to be resolved (resolved=True)
|
||||
if all_working:
|
||||
# If all the equipments are "Available", set Breakage Report to be resolved (resolved=True)
|
||||
if all_available:
|
||||
associated_breakage_report.resolved = True
|
||||
associated_breakage_report.save()
|
||||
|
||||
|
|
|
@ -1020,6 +1020,37 @@ paths:
|
|||
schema:
|
||||
$ref: '#/components/schemas/Transaction'
|
||||
description: ''
|
||||
patch:
|
||||
operationId: api_v1_transactions_partial_update
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
schema:
|
||||
type: integer
|
||||
description: A unique integer value identifying this transaction.
|
||||
required: true
|
||||
tags:
|
||||
- api
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PatchedTransaction'
|
||||
application/x-www-form-urlencoded:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PatchedTransaction'
|
||||
multipart/form-data:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PatchedTransaction'
|
||||
security:
|
||||
- jwtAuth: []
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Transaction'
|
||||
description: ''
|
||||
components:
|
||||
schemas:
|
||||
Activation:
|
||||
|
@ -1106,6 +1137,7 @@ components:
|
|||
type: string
|
||||
description:
|
||||
type: string
|
||||
maxLength: 512
|
||||
category:
|
||||
$ref: '#/components/schemas/CategoryEnum'
|
||||
last_updated:
|
||||
|
@ -1121,7 +1153,6 @@ components:
|
|||
readOnly: true
|
||||
required:
|
||||
- date_added
|
||||
- description
|
||||
- id
|
||||
- last_updated
|
||||
- last_updated_by
|
||||
|
@ -1144,6 +1175,7 @@ components:
|
|||
$ref: '#/components/schemas/StatusEnum'
|
||||
remarks:
|
||||
type: string
|
||||
maxLength: 512
|
||||
last_updated:
|
||||
type: string
|
||||
format: date-time
|
||||
|
@ -1367,6 +1399,7 @@ components:
|
|||
type: string
|
||||
description:
|
||||
type: string
|
||||
maxLength: 512
|
||||
category:
|
||||
$ref: '#/components/schemas/CategoryEnum'
|
||||
last_updated:
|
||||
|
@ -1398,6 +1431,7 @@ components:
|
|||
$ref: '#/components/schemas/StatusEnum'
|
||||
remarks:
|
||||
type: string
|
||||
maxLength: 512
|
||||
last_updated:
|
||||
type: string
|
||||
format: date-time
|
||||
|
@ -1409,6 +1443,26 @@ components:
|
|||
type: string
|
||||
format: date-time
|
||||
readOnly: true
|
||||
PatchedTransaction:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
readOnly: true
|
||||
borrower:
|
||||
type: integer
|
||||
teacher:
|
||||
type: integer
|
||||
equipments:
|
||||
type: array
|
||||
items:
|
||||
type: integer
|
||||
transaction_status:
|
||||
$ref: '#/components/schemas/TransactionStatusEnum'
|
||||
timestamp:
|
||||
type: string
|
||||
format: date-time
|
||||
readOnly: true
|
||||
SendEmailReset:
|
||||
type: object
|
||||
properties:
|
||||
|
@ -1444,12 +1498,12 @@ components:
|
|||
- new_username
|
||||
StatusEnum:
|
||||
enum:
|
||||
- Working
|
||||
- Available
|
||||
- Broken
|
||||
- Borrowed
|
||||
type: string
|
||||
description: |-
|
||||
* `Working` - Working
|
||||
* `Available` - Available
|
||||
* `Broken` - Broken
|
||||
* `Borrowed` - Borrowed
|
||||
TokenObtainPair:
|
||||
|
@ -1500,11 +1554,8 @@ components:
|
|||
readOnly: true
|
||||
borrower:
|
||||
type: integer
|
||||
nullable: true
|
||||
teacher:
|
||||
type: string
|
||||
format: uri
|
||||
nullable: true
|
||||
type: integer
|
||||
equipments:
|
||||
type: array
|
||||
items:
|
||||
|
@ -1516,7 +1567,10 @@ components:
|
|||
format: date-time
|
||||
readOnly: true
|
||||
required:
|
||||
- borrower
|
||||
- equipments
|
||||
- id
|
||||
- teacher
|
||||
- timestamp
|
||||
- transaction_status
|
||||
TransactionStatusEnum:
|
||||
|
|
|
@ -99,7 +99,7 @@ class TransactionSerializer(serializers.HyperlinkedModelSerializer):
|
|||
equipments = validated_data['equipments']
|
||||
for equipment in equipments:
|
||||
existing__pending_transactions = Transaction.objects.filter(
|
||||
equipments=equipment, status__in=['Pending', 'Approved', 'Borrowed', 'With Breakages: Pending Resolution'])
|
||||
equipments=equipment, transaction_status__in=['Pending', 'Approved', 'Borrowed', 'With Breakages: Pending Resolution'])
|
||||
if existing__pending_transactions.exists():
|
||||
raise serializers.ValidationError(
|
||||
f"Cannot add Equipment #{equipment.id}. It is still part of a non-finalized transaction")
|
||||
|
@ -110,13 +110,13 @@ class TransactionSerializer(serializers.HyperlinkedModelSerializer):
|
|||
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.technician and 'transaction_status' in validated_data and validated_data['transaction_status'] != instance.status:
|
||||
if not user.is_teacher and not user.is_technician and 'transaction_status' in validated_data and validated_data['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.status:
|
||||
if not user.is_teacher and 'transaction_status' in validated_data and validated_data['transaction_status'] != instance.transaction_status:
|
||||
raise serializers.ValidationError(
|
||||
"You do not have permission to change the status of a transaction"
|
||||
)
|
||||
|
@ -128,7 +128,7 @@ class TransactionSerializer(serializers.HyperlinkedModelSerializer):
|
|||
|
||||
# For already finalized/done transactions (Rejected or Finalized ones)
|
||||
# Do not allow any changes to already finalized transactions
|
||||
if instance.status in ['Rejected', 'Finalized']:
|
||||
if instance.transaction_status in ['Rejected', 'Finalized']:
|
||||
raise serializers.ValidationError(
|
||||
"Unable to update rejected or finalized transaction. Please create a new one"
|
||||
)
|
||||
|
@ -138,7 +138,7 @@ class TransactionSerializer(serializers.HyperlinkedModelSerializer):
|
|||
|
||||
# For Pending transactions
|
||||
# If not changing to Approved or Rejected, throw an error
|
||||
if instance.status == 'Pending' and validated_data['transaction_status'] != 'Approved' or validated_data['transaction_status'] != 'Rejected':
|
||||
if instance.transaction_status == "Pending" and (validated_data['transaction_status'] != "Approved" or validated_data['transaction_status'] != "Rejected"):
|
||||
raise serializers.ValidationError(
|
||||
"A pending transaction can only change to Approved or Rejected"
|
||||
)
|
||||
|
@ -146,7 +146,7 @@ class TransactionSerializer(serializers.HyperlinkedModelSerializer):
|
|||
# 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.status == 'Approved' and validated_data['transaction_status'] != 'Borrowed' or validated_data != 'Cancelled':
|
||||
if instance.transaction_status == "Approved" and (validated_data['transaction_status'] != "Borrowed" or validated_data != "Cancelled"):
|
||||
raise serializers.ValidationError(
|
||||
"An already approved transaction can only changed to Borrowed (On borrow) or Cancelled"
|
||||
)
|
||||
|
@ -154,7 +154,7 @@ class TransactionSerializer(serializers.HyperlinkedModelSerializer):
|
|||
# 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.status == 'Borrowed' and validated_data['transaction_status'] != 'Finalized' or validated_data != 'With Breakages: Pending Resolution':
|
||||
if instance.transaction_status == "Borrowed" and (validated_data['transaction_status'] != "Finalized" or validated_data != "With Breakages: Pending Resolution"):
|
||||
raise serializers.ValidationError(
|
||||
"A borrowed transaction can only changed to status of Finalized or With Breakages: Pending Resolution"
|
||||
)
|
||||
|
@ -162,7 +162,7 @@ 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.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 (validated_data['transaction_status'] != "Finalized" or validated_data != "With Breakages: Pending Resolution"):
|
||||
raise serializers.ValidationError(
|
||||
"A borrowed transaction can only changed to status of Finalized or With Breakages: Pending Resolution"
|
||||
)
|
||||
|
@ -170,27 +170,27 @@ class TransactionSerializer(serializers.HyperlinkedModelSerializer):
|
|||
# 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.status == 'With Breakages: Pending Resolution':
|
||||
if instance.transaction_status == "With Breakages: Pending Resolution":
|
||||
raise serializers.ValidationError(
|
||||
"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.status == 'Approved' and validated_data['transaction_status'] == 'Borrowed':
|
||||
if instance.transaction_status == "Approved" and validated_data['transaction_status'] == "Borrowed":
|
||||
equipments = validated_data.get('equipments', [])
|
||||
for equipment in equipments:
|
||||
equipment.status = 'Borrowed'
|
||||
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 Working again from Borrowed
|
||||
if instance.status == 'Borrowed' and validated_data['transaction_status'] == 'Finalized':
|
||||
# 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.status = 'Working'
|
||||
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.status == 'Borrowed' and validated_data['transaction_status'] == 'Finalized':
|
||||
if instance.transaction_status == "Borrowed" and validated_data['transaction_status'] == "Finalized":
|
||||
BreakageReport.objects.create(
|
||||
transaction=instance,
|
||||
equipments=instance.equipments.all(),
|
||||
|
|
|
@ -7,7 +7,7 @@ from .models import Transaction
|
|||
class TransactionViewSet(viewsets.ModelViewSet):
|
||||
# Only allow GET, POST/CREATE
|
||||
# Transactions cannot be deleted
|
||||
http_method_names = ['get', 'post']
|
||||
http_method_names = ['get', 'post', 'patch']
|
||||
permission_classes = [IsAuthenticated]
|
||||
serializer_class = TransactionSerializer
|
||||
queryset = Transaction.objects.all()
|
||||
|
|
Loading…
Reference in a new issue