def clean_obsolete_subscriptions(): """Clean obsoletes subscriptions from all patrons. Search for all patron with obsolete subscriptions. For each found patron clean the subscription array keeping only subscription with a end-time grower than now(). Update patron to commit change """ def is_obsolete(subscription, end_date=None): """Check if a subscription is obsolete by checking end date.""" if end_date is None: end_date = datetime.now() sub_end_date = subscription.get('end_date', '1970-01-01') sub_end_date = datetime.strptime(sub_end_date, '%Y-%m-%d') return sub_end_date < end_date for patron in Patron.patrons_with_obsolete_subscription_pids(): subscriptions = patron.get('subscriptions', []) subscriptions = [sub for sub in subscriptions if not is_obsolete(sub)] if not subscriptions and 'subscriptions' in patron: del patron['subscriptions'] else: patron['subscriptions'] = subscriptions # NOTE : this update will trigger the listener # `create_subscription_patron_transaction`. This listener will # create a new subscription if needed patron.update(patron.dumps(), dbcommit=True, reindex=True)
def test_patron_has_valid_subscriptions(patron_type_grown_sion, patron_sion, patron_sion_data, patron_type_adults_martigny, patron2_martigny, patron_type_youngsters_sion): """Test patron subscriptions.""" patron_sion = patron_sion patron_martigny = patron2_martigny # 'patron_type_adults_martigny' doesn't require any subscription # 'patron2_martigny' is linked to it, so `has_valid_subscription` # should return True assert not patron_type_adults_martigny.is_subscription_required assert patron_martigny.has_valid_subscription # 'patron_type_grown_sion' require a subscription # removed all stored subscription and test if subscription exists if patron_sion.get('patron', {}).get('subscriptions'): del patron_sion['patron']['subscriptions'] assert patron_type_grown_sion.is_subscription_required assert not patron_sion.has_valid_subscription # Create a subscription for this patron and check this subscription is # stored and valid start = datetime.now() - timedelta(seconds=10) end = datetime.now() + timedelta(days=10) patron_sion.add_subscription(patron_type_grown_sion, start, end) assert patron_sion.has_valid_subscription assert len(patron_sion.get_valid_subscriptions()) == 1 subscription = patron_sion.get_valid_subscriptions()[0] assert subscription.get('start_date') == start.strftime('%Y-%m-%d') # Create a old subscription for this patron and check validity start = datetime.now() - timedelta(days=20) end = start + timedelta(days=10) patron_sion.add_subscription(patron_type_grown_sion, start, end) assert len(patron_sion.get('patron', {}).get('subscriptions', [])) == 2 assert len(patron_sion.get_valid_subscriptions()) == 1 # remove old subscriptions. Create an old one and check the patron doesn't # have any valid subscription del patron_sion['patron']['subscriptions'] patron_sion.add_subscription(patron_type_grown_sion, start, end) # !! As `add_subscription` use the method `Patron.update`, then the signal # `after_record_update` are send by invenio_records and the patron # listener `create_subscription_patron_transaction` is called. This # listener found that user doesn't have any subscription and add a valid # one for this patron. So after `add_subscription` call, I just removed # the valid subscription created. del patron_sion['patron']['subscriptions'][1] assert not patron_sion.has_valid_subscription # remove all subscriptions. Create a valid subscription other patron_type # than current patron.patron_type. Check if the patron has a valid # subscription del patron_sion['patron']['subscriptions'] start = datetime.now() - timedelta(seconds=10) end = datetime.now() + timedelta(days=10) patron_sion.add_subscription(patron_type_youngsters_sion, start, end) assert patron_sion.has_valid_subscription # Create a old subscription for `patron_sion`. Call ES to know patrons with # an obsolete subscription. This query should return the recently updated # patron. start = datetime.now() - timedelta(days=20) end = start + timedelta(days=10) patron_sion.add_subscription(patron_type_youngsters_sion, start, end) patron_sion.add_subscription(patron_type_grown_sion, start, end) patrons = list(Patron.patrons_with_obsolete_subscription_pids()) assert len(patrons) == 1 and patrons[0].pid == patron_sion.pid # same check for a very old end_date end_date = end - timedelta(days=100) patrons = list(Patron.patrons_with_obsolete_subscription_pids(end_date)) assert len(patrons) == 0 # Reset the patron as at the beginning del patron_sion['patron']['subscriptions'] start = datetime.now() end = datetime.now() + timedelta(days=10) patron_sion.add_subscription(patron_type_grown_sion, start, end)