Repository: fossasia/open-event-server

Issue:
Cron job for marking event invoices due is wrong
PR https://github.com/fossasia/open-event-server/pull/6166 is wrong. The query fails in every case

https://github.com/fossasia/open-event-server/blob/bc45c1d267b924b556d36855f29c1dd96e901209/app/api/helpers/scheduled_jobs.py#L164-L174

This line is not valid SQLAlchemy syntax:

https://github.com/fossasia/open-event-server/blob/bc45c1d267b924b556d36855f29c1dd96e901209/app/api/helpers/scheduled_jobs.py#L169

`Neither 'InstrumentedAttribute' object nor 'Comparator' object associated with EventInvoice.event has an attribute 'ends_at'`

It should be `db.session.query(EventInvoice).join(Event).filter(EventInvoice.status == 'upcoming', Event.ends_at >= datetime.datetime.now()).all()`

Each run of this task is failing

Fix it and write tests to ensure it is working


Discussion:
@iamareebjamal I would like to take this one if no one is working on it.
Go ahead. This is high priority issue so please try to submit a PR within few days
@iamareebjamal are there any tests written for scheduled jobs?
For some of them, it might be written, I'm not sure
@arpit551 If you're pre-occupied elsewhere, I'll go ahead & fix this. 
@mrsaicharan1 Please go ahead, this is high priority

Resolving patch:
diff --git a/app/api/helpers/scheduled_jobs.py b/app/api/helpers/scheduled_jobs.py
--- a/app/api/helpers/scheduled_jobs.py
+++ b/app/api/helpers/scheduled_jobs.py
@@ -164,14 +164,12 @@ def expire_pending_tickets():
 def event_invoices_mark_due():
     from app import current_app as app
     with app.app_context():
-        db.session.query(EventInvoice).\
-                    filter(EventInvoice.status == 'upcoming',
-                           EventInvoice.event.ends_at >= datetime.datetime.now(),
-                           (EventInvoice.created_at + datetime.timedelta(days=30) <=
-                            datetime.datetime.now())).\
-                    update({'status': 'due'})
-
-        db.session.commit()
+        db.session.query(EventInvoice).filter(
+            EventInvoice.status == 'upcoming',
+            Event.id == EventInvoice.event_id,
+            Event.ends_at >= datetime.datetime.now(),
+            (EventInvoice.created_at + datetime.timedelta(days=30) <= datetime.datetime.now())
+        ).update({EventInvoice.status: 'due'}, synchronize_session=False)
 
 
 def send_monthly_event_invoice():


Test patch:
diff --git a/tests/all/integration/api/helpers/test_scheduled_jobs.py b/tests/all/integration/api/helpers/test_scheduled_jobs.py
new file mode 100644
--- /dev/null
+++ b/tests/all/integration/api/helpers/test_scheduled_jobs.py
@@ -0,0 +1,31 @@
+import datetime
+
+from app import current_app as app, db
+from app.factories.event_invoice import EventInvoiceFactory
+from app.models.event_invoice import EventInvoice
+from app.api.helpers.scheduled_jobs import event_invoices_mark_due
+
+from tests.all.integration.utils import OpenEventTestCase
+
+
+class TestScheduledJobs(OpenEventTestCase):
+
+    def test_event_invoices_mark_due(self):
+        """Method to test marking of event invoices as due"""
+
+        with app.test_request_context():
+            event_invoice_new = EventInvoiceFactory(event__ends_at=datetime.datetime(2019, 7, 20))
+            event_invoice_paid = EventInvoiceFactory(status="paid")
+
+            db.session.commit()
+
+            event_invoice_new_id = event_invoice_new.id
+            event_invoice_paid_id = event_invoice_paid.id
+
+            event_invoices_mark_due()
+
+            status_new = EventInvoice.query.get(event_invoice_new_id).status
+            status_paid = EventInvoice.query.get(event_invoice_paid_id).status
+
+            self.assertEqual(status_new, "due")
+            self.assertNotEqual(status_paid, "due")