Repository: fossasia/open-event-server

Issue:
Tax information not being carried on event copy action
**Describe the bug**
<!-- A clear and concise description of what the bug is. -->
Copying an event with tax information isn't copying the tax information too.

Main event : 
![image](https://user-images.githubusercontent.com/21087061/61944379-2bcb4e00-afbb-11e9-896e-88ec929f5c68.png)

Copied event :
![image](https://user-images.githubusercontent.com/21087061/61944473-5a492900-afbb-11e9-9a8a-16ea33c3e59c.png)

**Expected behavior**
<!-- A clear and concise description of what you expected to happen. -->
tax information should've been copied too


Discussion:
Issue-Label Bot is automatically applying the label `bug` to this issue, with a confidence of 0.97. Please mark this comment with :thumbsup: or :thumbsdown: to give our bot feedback! 

 Links: [app homepage](https://github.com/marketplace/issue-label-bot), [dashboard](https://mlbot.net/data/fossasia/open-event-server) and [code](https://github.com/hamelsmu/MLapp) for this bot.

Resolving patch:
diff --git a/app/api/event_copy.py b/app/api/event_copy.py
--- a/app/api/event_copy.py
+++ b/app/api/event_copy.py
@@ -15,6 +15,7 @@
 from app.models.ticket import Ticket
 from app.models.track import Track
 from app.models.users_events_role import UsersEventsRoles
+from app.models.tax import Tax
 
 event_copy = Blueprint('event_copy', __name__, url_prefix='/v1/events')
 
@@ -23,6 +24,14 @@ def start_sponsor_logo_generation_task(event_id):
     from .helpers.tasks import sponsor_logos_url_task
     sponsor_logos_url_task.delay(event_id=event_id)
 
+
+def copy_to_event(object, event):
+    db.session.expunge(object)  # expunge the object
+    make_transient(object)
+    object.event_id = event.id
+    delattr(object, 'id')
+    save_to_db(object)
+
 @event_copy.route('/<identifier>/copy', methods=['POST'])
 def create_event_copy(identifier):
     id = 'identifier'
@@ -36,15 +45,16 @@ def create_event_copy(identifier):
         return abort(
             make_response(jsonify(error="Access Forbidden"), 403)
         )
-    tickets = Ticket.query.filter_by(event_id=event.id).all()
-    social_links = SocialLink.query.filter_by(event_id=event.id).all()
-    sponsors = Sponsor.query.filter_by(event_id=event.id).all()
-    microlocations = Microlocation.query.filter_by(event_id=event.id).all()
-    tracks = Track.query.filter_by(event_id=event.id).all()
-    custom_forms = CustomForms.query.filter_by(event_id=event.id).all()
-    discount_codes = DiscountCode.query.filter_by(event_id=event.id).all()
-    speaker_calls = SpeakersCall.query.filter_by(event_id=event.id).all()
-    user_event_roles = UsersEventsRoles.query.filter_by(event_id=event.id).all()
+    tickets = Ticket.query.filter_by(event_id=event.id, deleted_at=None).all()
+    social_links = SocialLink.query.filter_by(event_id=event.id, deleted_at=None).all()
+    sponsors = Sponsor.query.filter_by(event_id=event.id, deleted_at=None).all()
+    microlocations = Microlocation.query.filter_by(event_id=event.id, deleted_at=None).all()
+    tracks = Track.query.filter_by(event_id=event.id, deleted_at=None).all()
+    custom_forms = CustomForms.query.filter_by(event_id=event.id, deleted_at=None).all()
+    discount_codes = DiscountCode.query.filter_by(event_id=event.id, deleted_at=None).all()
+    speaker_calls = SpeakersCall.query.filter_by(event_id=event.id, deleted_at=None).all()
+    user_event_roles = UsersEventsRoles.query.filter_by(event_id=event.id, deleted_at=None).all()
+    taxes = Tax.query.filter_by(event_id=event.id, deleted_at=None).all()
 
     db.session.expunge(event)  # expunge the object from session
     make_transient(event)
@@ -52,81 +62,40 @@ def create_event_copy(identifier):
     event.identifier = get_new_event_identifier()
     save_to_db(event)
 
+    # Ensure tax information is copied
+    for tax in taxes:
+        copy_to_event(tax, event)
+
     # Removes access_codes, order_tickets, ticket_tags for the new tickets created.
     for ticket in tickets:
-        ticket_id = ticket.id
-        db.session.expunge(ticket)  # expunge the object from session
-        make_transient(ticket)
-        ticket.event_id = event.id
-        delattr(ticket, 'id')
-        save_to_db(ticket)
+        copy_to_event(ticket, event)
 
     for link in social_links:
-        link_id = link.id
-        db.session.expunge(link)  # expunge the object from session
-        make_transient(link)
-        link.event_id = event.id
-        delattr(link, 'id')
-        save_to_db(link)
+        copy_to_event(link, event)
 
     for sponsor in sponsors:
-        sponsor_id = sponsor.id
-        db.session.expunge(sponsor)  # expunge the object from session
-        make_transient(sponsor)
-        sponsor.event_id = event.id
-        delattr(sponsor, 'id')
-        save_to_db(sponsor)
+        copy_to_event(sponsor, event)
 
     start_sponsor_logo_generation_task(event.id)
 
     for location in microlocations:
-        location_id = location.id
-        db.session.expunge(location)  # expunge the object from session
-        make_transient(location)
-        location.event_id = event.id
-        delattr(location, 'id')
-        save_to_db(location)
+        copy_to_event(location, event)
 
     # No sessions are copied for new tracks
     for track in tracks:
-        track_id = track.id
-        db.session.expunge(track)  # expunge the object from session
-        make_transient(track)
-        track.event_id = event.id
-        delattr(track, 'id')
-        save_to_db(track)
+        copy_to_event(track, event)
 
     for call in speaker_calls:
-        call_id = call.id
-        db.session.expunge(call)  # expunge the object from session
-        make_transient(call)
-        call.event_id = event.id
-        delattr(call, 'id')
-        save_to_db(call)
+        copy_to_event(call, event)
 
     for code in discount_codes:
-        code_id = code.id
-        db.session.expunge(code)  # expunge the object from session
-        make_transient(code)
-        code.event_id = event.id
-        delattr(code, 'id')
-        save_to_db(code)
+        copy_to_event(code, event)
 
     for form in custom_forms:
-        form_id = form.id
-        db.session.expunge(form)  # expunge the object from session
-        make_transient(form)
-        form.event_id = event.id
-        delattr(form, 'id')
-        save_to_db(form)
+        copy_to_event(form, event)
 
     for user_role in user_event_roles:
-        user_role_id = user_role.id
-        db.session.expunge(user_role)
-        make_transient(user_role)
-        user_role.event_id = event.id
-        delattr(user_role, 'id')
-        save_to_db(user_role)
+        copy_to_event(user_role, event)
 
     return jsonify({
         'id': event.id,


Test patch: