internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: fossasia/open-event-server

Issue:
Migration for message settings throws error
**Describe the bug**
Migration file for message settings - [`163f9fc56815_.py`](https://github.com/fossasia/open-event-server/blob/development/migrations/versions/163f9fc56815_.py) (added in #5042) leads to a SQLAlchemy `ProgrammingError` when upgrading.

**To Reproduce**
Steps to reproduce the behavior:
Upgrade your database instance to head `163f9fc56815` via `python manage.py db upgrade`

**Expected behavior**
Database should upgrade successfully.

**Stacktrace**
```
sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) column "mail_status" cannot be cast automatically to type boolean
HINT:  You might need to specify "USING mail_status::boolean".
 [SQL: 'ALTER TABLE message_settings ALTER COLUMN mail_status TYPE BOOLEAN ']
```
I'll add raw SQL in the migration file to fix this.


Discussion:

Resolving patch:
diff --git a/migrations/versions/163f9fc56815_.py b/migrations/versions/163f9fc56815_.py
--- a/migrations/versions/163f9fc56815_.py
+++ b/migrations/versions/163f9fc56815_.py
@@ -18,18 +18,15 @@
 def upgrade():
     # ### commands auto generated by Alembic - please adjust! ###
     op.add_column('message_settings', sa.Column('sent_at', sa.DateTime(timezone=True), nullable=True))
-    op.alter_column('message_settings', 'mail_status',
-               existing_type=sa.INTEGER(),
-               type_=sa.Boolean(),
-               existing_nullable=True)
-    op.alter_column('message_settings', 'notification_status',
-               existing_type=sa.INTEGER(),
-               type_=sa.Boolean(),
-               existing_nullable=True)
-    op.alter_column('message_settings', 'user_control_status',
-               existing_type=sa.INTEGER(),
-               type_=sa.Boolean(),
-               existing_nullable=True)
+    op.execute(
+        "ALTER TABLE message_settings ALTER COLUMN mail_status TYPE BOOLEAN "
+        "USING mail_status::boolean")
+    op.execute(
+        "ALTER TABLE message_settings ALTER COLUMN notification_status "
+        "TYPE BOOLEAN USING notification_status::boolean")
+    op.execute(
+        "ALTER TABLE message_settings ALTER COLUMN user_control_status "
+        "TYPE BOOLEAN USING user_control_status::boolean")
     # ### end Alembic commands ###
 
 


Test patch:
Repository: fossasia/open-event-server

Issue:
Add Dredd tests for Message Settings API
**Is your feature request related to a problem? Please describe.**
<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->
Add Dredd tests for Message Settings API

**Describe the solution you'd like**
<!-- A clear and concise description of what you want to happen. -->

**Describe alternatives you've considered**
<!-- A clear and concise description of any alternative solutions or features you've considered. -->

**Additional context**
<!-- Add any other context or screenshots about the feature request here. -->

**Working on this**


Discussion:

Resolving patch:
diff --git a/app/factories/message_setting.py b/app/factories/message_setting.py
new file mode 100644
--- /dev/null
+++ b/app/factories/message_setting.py
@@ -0,0 +1,14 @@
+import factory
+
+from app.models.message_setting import db, MessageSettings
+
+
+class MessageSettingsFactory(factory.alchemy.SQLAlchemyModelFactory):
+    class Meta:
+        model = MessageSettings
+        sqlalchemy_session = db.session
+
+    action = "After Event"
+    mail_status = True
+    notification_status = True
+    user_control_status = True


Test patch:
diff --git a/tests/hook_main.py b/tests/hook_main.py
--- a/tests/hook_main.py
+++ b/tests/hook_main.py
@@ -55,6 +55,7 @@
 from app.factories.faq_type import FaqTypeFactory
 from app.factories.feedback import FeedbackFactory
 from app.factories.service import ServiceFactory
+from app.factories.message_setting import MessageSettingsFactory
 
 
 
@@ -2302,6 +2303,46 @@ def event_role_permission_patch(transaction):
 #       db.session.commit()
 
 
+# ------------------------- Message Setting -------------------------
+@hooks.before("Message Settings > Message Setting Collection > List Message Settings")
+def message_setting_list(transaction):
+    """
+    GET /message-settings
+    :param transaction:
+    :return:
+    """
+    with stash['app'].app_context():
+        message_setting = MessageSettingsFactory()
+        db.session.add(message_setting)
+        db.session.commit()
+
+
+@hooks.before("Message Settings > Message Setting Details > Get Message Setting Details")
+def message_setting_detail(transaction):
+    """
+    GET /message-settings/1
+    :param transaction:
+    :return:
+    """
+    with stash['app'].app_context():
+        message_setting = MessageSettingsFactory()
+        db.session.add(message_setting)
+        db.session.commit()
+
+
+@hooks.before("Message Settings > Message Setting Details > Update Message Setting")
+def message_setting_patch(transaction):
+    """
+    PATCH /message-settings/1
+    :param transaction:
+    :return:
+    """
+    with stash['app'].app_context():
+        message_setting = MessageSettingsFactory()
+        db.session.add(message_setting)
+        db.session.commit()
+
+
 # ------------------------- Activities -------------------------
 @hooks.before("Activity > Activity Collection > List all Activities")
 def activity_get_list(transaction):
Repository: fossasia/open-event-server

Issue:
HTTP 422 wrongly raised for Discount code when min-qty is equal to max-qty
**Describe the bug**
<!-- A clear and concise description of what the bug is. -->
The server returns HTTP 422 when post request is made to create a discount code whose min-qty is equal to max-qty. 
```
{"errors": [{"status": 422, "source": {"pointer": "/data/attributes/min-quantity"}, "title": "Unprocessable Entity", "detail": "min-quantity should be less than max-quantity"}], "jsonapi": {"version": "1.0"}}
```

**Expected behavior**
<!-- A clear and concise description of what you expected to happen. -->
It should allow equality.


Discussion:
I would like to work on this

Resolving patch:
diff --git a/app/api/schema/discount_codes.py b/app/api/schema/discount_codes.py
--- a/app/api/schema/discount_codes.py
+++ b/app/api/schema/discount_codes.py
@@ -47,10 +47,10 @@ def quantity_validation_helper(obj, data):
         min_quantity = data.get('min_quantity', None)
         max_quantity = data.get('max_quantity', None)
         if min_quantity is not None and max_quantity is not None:
-            if min_quantity >= max_quantity:
+            if min_quantity > max_quantity:
                 raise UnprocessableEntity(
                     {'pointer': '/data/attributes/min-quantity'},
-                    "min-quantity should be less than max-quantity"
+                    "min-quantity cannot be more than max-quantity"
                 )
 
 


Test patch:
Repository: fossasia/open-event-server

Issue:
Expire the order after payment failure and delete the attendees in order to unlock the tickets
**Is your feature request related to a problem? Please describe.**
<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->
Right now we don't expire the order and delete the attendees after payment failure. 

**Describe the solution you'd like**
<!-- A clear and concise description of what you want to happen. -->
It should be done so that the locked tickets can be unlocked.

**Additional context**
<!-- Add any other context or screenshots about the feature request here. -->
Parent #4852 



Discussion:

Resolving patch:
diff --git a/app/api/helpers/ticketing.py b/app/api/helpers/ticketing.py
--- a/app/api/helpers/ticketing.py
+++ b/app/api/helpers/ticketing.py
@@ -6,6 +6,7 @@
 from app.api.helpers.files import make_frontend_url
 from app.api.helpers.mail import send_email_to_attendees
 from app.api.helpers.notification import send_notif_to_attendees, send_notif_ticket_purchase_organizer
+from app.api.helpers.order import delete_related_attendees_for_order
 from app.api.helpers.payment import StripePaymentsManager, PayPalPaymentsManager
 from app.models import db
 from app.models.ticket_fee import TicketFees
@@ -113,7 +114,14 @@ def charge_stripe_order_payment(order, token_id):
 
             return True, order
         else:
-            # payment failed hence return the failure message from stripe.
+            # payment failed hence expire the order
+            order.status = 'expired'
+            save_to_db(order)
+
+            # delete related attendees to unlock the tickets
+            delete_related_attendees_for_order(db, order)
+
+            # return the failure message from stripe.
             return False, charge.failure_message
 
     @staticmethod
@@ -151,6 +159,14 @@ def charge_paypal_order_payment(order, token_id):
 
                 return True, order
             else:
+                # payment failed hence expire the order
+                order.status = 'expired'
+                save_to_db(order)
+
+                # delete related attendees to unlock the tickets
+                delete_related_attendees_for_order(db, order)
+
+                # return the error message from Paypal
                 return False, capture_result['L_SHORTMESSAGE0']
         else:
             return False, 'Payer ID missing. Payment flow tampered.'


Test patch:
Repository: fossasia/open-event-server

Issue:
Add orders relationship in user schema
**Is your feature request related to a problem? Please describe.**
<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->
Add orders relationship in user schema.


Discussion:

Resolving patch:
diff --git a/app/api/__init__.py b/app/api/__init__.py
--- a/app/api/__init__.py
+++ b/app/api/__init__.py
@@ -95,6 +95,8 @@
 api.route(UserRelationship, 'user_moderator_event', '/users/<int:id>/relationships/moderator-events')
 api.route(UserRelationship, 'user_attendees', '/users/<int:id>/relationships/attendees')
 api.route(UserRelationship, 'user_events', '/users/<int:id>/relationships/events')
+api.route(UserRelationship, 'user_orders', '/users/<int:id>/relationships/orders')
+
 
 # notifications
 api.route(NotificationListAdmin, 'notification_list_admin', '/notifications')
diff --git a/app/api/schema/users.py b/app/api/schema/users.py
--- a/app/api/schema/users.py
+++ b/app/api/schema/users.py
@@ -183,3 +183,12 @@ class Meta:
         schema='EventSchema',
         many=True,
         type_='event')
+    orders = Relationship(
+        attribute='orders',
+        self_view='v1.user_orders',
+        self_view_kwargs={'id': '<id>'},
+        related_view='v1.orders_list',
+        related_view_kwargs={'user_id': '<id>'},
+        schema='OrderSchema',
+        many=True,
+        type_='order')


Test patch:
Repository: fossasia/open-event-server

Issue:
Add docs for Charges layer
**Is your feature request related to a problem? Please describe.**
<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->
The API docs need to have samples for charges layer. 

**Additional context**
<!-- Add any other context or screenshots about the feature request here. -->
Parent issue #4852 


Discussion:

Resolving patch:
diff --git a/app/api/__init__.py b/app/api/__init__.py
--- a/app/api/__init__.py
+++ b/app/api/__init__.py
@@ -513,7 +513,7 @@
           '/attendees/<int:attendee_id>/order')
 
 # Charges API
-api.route(ChargeList, 'charge_list', '/orders/<identifier>/charge', '/orders/<order_identifier>/charge')
+api.route(ChargeList, 'charge_list', '/orders/<order_identifier>/charge')
 api.route(OrderRelationship, 'order_attendee', '/orders/<order_identifier>/relationships/attendee')
 api.route(OrderRelationship, 'order_ticket', '/orders/<order_identifier>/relationships/ticket')
 api.route(OrderRelationship, 'order_user', '/orders/<order_identifier>/relationships/user')
diff --git a/app/api/data_layers/ChargesLayer.py b/app/api/data_layers/ChargesLayer.py
--- a/app/api/data_layers/ChargesLayer.py
+++ b/app/api/data_layers/ChargesLayer.py
@@ -16,7 +16,13 @@ def create_object(self, data, view_kwargs):
         :param view_kwargs:
         :return:
         """
-        order = Order.query.filter_by(id=view_kwargs['id']).first()
+
+        if view_kwargs.get('order_identifier').isdigit():
+            # when id is passed
+            order = Order.query.filter_by(id=view_kwargs['order_identifier']).first()
+        else:
+            # when identifier is passed
+            order = Order.query.filter_by(identifier=view_kwargs['order_identifier']).first()
         if not order:
             raise ObjectNotFound({'parameter': 'id'},
                                  "Order with id: {} not found".format(view_kwargs['id']))
diff --git a/app/api/orders.py b/app/api/orders.py
--- a/app/api/orders.py
+++ b/app/api/orders.py
@@ -327,7 +327,7 @@ class Meta:
         type_ = 'charge'
         inflect = dasherize
         self_view = 'v1.charge_list'
-        self_view_kwargs = {'id': '<id>'}
+        self_view_kwargs = {'order_identifier': '<id>'}
 
     id = fields.Str(dump_only=True)
     stripe = fields.Str(allow_none=True)
@@ -343,7 +343,8 @@ class ChargeList(ResourceList):
 
     data_layer = {
         'class': ChargesLayer,
-        'session': db.session
+        'session': db.session,
+        'model': Order
     }
 
     decorators = (jwt_required,)


Test patch:
diff --git a/tests/hook_main.py b/tests/hook_main.py
--- a/tests/hook_main.py
+++ b/tests/hook_main.py
@@ -3826,6 +3826,16 @@ def delete_order(transaction):
     transaction['skip'] = True
 
 
+@hooks.before("Orders > Charge > Charge for an Order")
+def orders_charge(transaction):
+    """
+    GET /orders/1/charge
+    :param transaction:
+    :return:
+    """
+    transaction['skip'] = True
+
+
 @hooks.before("Orders > Orders under a User > List all Orders under a User")
 def orders_get_collection_under_user(transaction):
     """
Repository: fossasia/open-event-server

Issue:
PATCH and DELETE endpoint on orders api returns 404
**Describe the bug**
All PATCH and DELETE requests on orders API return 404 response (object id not found)

**Expected behavior**
<!-- A clear and concise description of what you expected to happen. -->
Request should succeed.


Discussion:

Resolving patch:
diff --git a/app/api/__init__.py b/app/api/__init__.py
--- a/app/api/__init__.py
+++ b/app/api/__init__.py
@@ -509,7 +509,7 @@
 api.route(OrdersListPost, 'order_list_post', '/orders')
 api.route(OrdersList, 'orders_list', '/orders', '/events/<int:event_id>/orders',
           '/events/<event_identifier>/orders', '/users/<int:user_id>/orders')
-api.route(OrderDetail, 'order_detail', '/orders/<order_identifier>',
+api.route(OrderDetail, 'order_detail', '/orders/<int:id>', '/orders/<order_identifier>',
           '/attendees/<int:attendee_id>/order')
 
 # Charges API
diff --git a/app/api/orders.py b/app/api/orders.py
--- a/app/api/orders.py
+++ b/app/api/orders.py
@@ -200,8 +200,11 @@ def before_get_object(self, view_kwargs):
         if view_kwargs.get('attendee_id'):
             attendee = safe_query(self, TicketHolder, 'id', view_kwargs['attendee_id'], 'attendee_id')
             view_kwargs['order_identifier'] = attendee.order.identifier
-
-        order = safe_query(self, Order, 'identifier', view_kwargs['order_identifier'], 'order_identifier')
+        if view_kwargs.get('order_identifier'):
+            order = safe_query(self, Order, 'identifier', view_kwargs['order_identifier'], 'order_identifier')
+            view_kwargs['id'] = order.id
+        elif view_kwargs.get('id'):
+            order = safe_query(self, Order, 'id', view_kwargs['id'], 'id')
 
         if not has_access('is_coorganizer_or_user_itself', event_id=order.event_id, user_id=order.user_id):
             return ForbiddenException({'source': ''}, 'You can only access your orders or your event\'s orders')
@@ -292,8 +295,6 @@ def before_delete_object(self, order, view_kwargs):
     schema = OrderSchema
     data_layer = {'session': db.session,
                   'model': Order,
-                  'url_field': 'order_identifier',
-                  'id_field': 'identifier',
                   'methods': {
                       'before_update_object': before_update_object,
                       'before_delete_object': before_delete_object,


Test patch:
Repository: fossasia/open-event-server

Issue:
PATCH and DELETE request to orders api returns 403 (access forbidden)
**Describe the bug**
- PATCH request to update status of an order fails with `403: pointer | data/user detail | You cannot update user of an order`
- DELETE request fails with `403: pointer | data/deleted_at detail | You cannot update deleted_at of an order`

**Expected behavior**
Requests should succeed.




Discussion:

Resolving patch:
diff --git a/app/api/orders.py b/app/api/orders.py
--- a/app/api/orders.py
+++ b/app/api/orders.py
@@ -230,14 +230,15 @@ def before_update_object(self, order, data, view_kwargs):
             if current_user.id == order.user_id:
                 # Order created from the tickets tab.
                 for element in data:
-                    if data[element] != getattr(order, element, None) and element not in get_updatable_fields():
+                    if data[element] and data[element]\
+                            != getattr(order, element, None) and element not in get_updatable_fields():
                         raise ForbiddenException({'pointer': 'data/{}'.format(element)},
                                                  "You cannot update {} of an order".format(element))
 
             else:
                 # Order created from the public pages.
                 for element in data:
-                    if data[element] != getattr(order, element, None):
+                    if data[element] and data[element] != getattr(order, element, None):
                         if element != 'status':
                             raise ForbiddenException({'pointer': 'data/{}'.format(element)},
                                                      "You cannot update {} of an order".format(element))
@@ -256,7 +257,8 @@ def before_update_object(self, order, data, view_kwargs):
                                          "You cannot update a non-pending order")
             else:
                 for element in data:
-                    if data[element] != getattr(order, element, None) and element not in get_updatable_fields():
+                    if data[element] and data[element]\
+                            != getattr(order, element, None) and element not in get_updatable_fields():
                         raise ForbiddenException({'pointer': 'data/{}'.format(element)},
                                                  "You cannot update {} of an order".format(element))
 
diff --git a/app/models/order.py b/app/models/order.py
--- a/app/models/order.py
+++ b/app/models/order.py
@@ -21,7 +21,7 @@ def get_updatable_fields():
     """
     :return: The list of fields which can be modified by the order user using the pre payment form.
     """
-    return ['country', 'address', 'city', 'state', 'zipcode', 'status', 'paid_via', 'order_notes']
+    return ['country', 'address', 'city', 'state', 'zipcode', 'status', 'paid_via', 'order_notes', 'deleted_at', 'user']
 
 
 class OrderTicket(SoftDeletionModel):


Test patch:
Repository: fossasia/open-event-server

Issue:
Add created_at field to orders schema
**Describe the bug**
Currently created_at is added in orders model. We need this field to be rendered in FE so we should add it to schema as well.


Discussion:

Resolving patch:
diff --git a/app/api/schema/orders.py b/app/api/schema/orders.py
--- a/app/api/schema/orders.py
+++ b/app/api/schema/orders.py
@@ -47,6 +47,7 @@ def initial_values(self, data):
     country = fields.Str(allow_none=True)
     zipcode = fields.Str(allow_none=True)
     completed_at = fields.DateTime(dump_only=True)
+    created_at = fields.DateTime(dump_only=True)
     transaction_id = fields.Str(dump_only=True)
     payment_mode = fields.Str(default="free",
                               validate=validate.OneOf(choices=["free", "stripe", "paypal"]))


Test patch:
Repository: fossasia/open-event-server

Issue:
Do not allow duplicate speaker creation
**Describe the bug**
Currently, there can be infinite speakers with the same email address resulting in duplicate entries.

**To Reproduce**
Steps to reproduce the behavior:
1. Create a speaker
2. Create another with the same email-id

**Expected behavior**
An error should be raised in such a situation.

**Additional details (please complete the following information):**
 - OS: Ubuntu 18.04
 - Python Version 3.6

**Additional context**
Since the front end now supports the addition of existing speakers while creating a session, this issue can be solved.


Discussion:

Resolving patch:
diff --git a/app/api/speakers.py b/app/api/speakers.py
--- a/app/api/speakers.py
+++ b/app/api/speakers.py
@@ -40,6 +40,10 @@ def before_post(self, args, kwargs, data):
         if get_count(db.session.query(Event).filter_by(id=int(data['event']), is_sessions_speakers_enabled=False)) > 0:
             raise ForbiddenException({'pointer': ''}, "Speakers are disabled for this Event")
 
+        if get_count(db.session.query(Speaker).filter_by(event_id=int(data['event']), email=data['email'],
+                                                         deleted_at=None)) > 0:
+            raise ForbiddenException({'pointer': ''}, 'Speaker with this Email ID already exists')
+
         if 'sessions' in data:
             session_ids = data['sessions']
             for session_id in session_ids:


Test patch: