---
# System prepended metadata

title: Untitled

---

## Shopify Sync improvements

@joaquinpunales1992 

**Can you run the command manually in the setup container (which has no memory limit).**

```
# Gets you into the container
docker-compose run --rm setup bash
```

```
# Once you're in the container
manage.py shell_plus
# ...
```

**Can you also add a celery task wrapping the call_command, so you can start your task manually within celery's queue**

```
# agsa/crm/tasks.py
from celery import task
from django.core.management import call_command

@task
def sync_shopify_discount_codes():
    call_command('sync_shopify_discount_codes')
```

```
# Settings
CELERYBEAT_SCHEDULE = {
    # ...
    'SyncShopifyDiscountCodes': {
        'task': 'agsa.crm.tasks.sync_shopify_discount_codes',
        'schedule': crontab(hour=7, minute=40),
    },
}
```

```
# in the shell
from agsa.crm.tasks import sync_shopify_discount_codes

sync_shopify_discount_codes.delay()
```

**Can you deploy your changes to production and then test the celery queue handles the new task.***

```
# Something like
docker-compose logs -f celery
```



```python
def _get_blackbaud_constituents():
    """
    Get saved blackbaud constituents (result of the 'sync_records_from_blackbaud' process) and classify them as
    primary (main) and secondary members
    :return: An array of primary constituents and an array of secondary constituents
    """
    main_members = []
    secondary_members = []
    
    constituent_bb_id_to_lookup_id = {}
    for obj in BlackbaudConstituent.objects.values('bb_id', 'lookup_id', 'data'):
        if obj['lookup_id']:
            constituent_lookup_id = obj.lookup_id
        elif 'lookup_id' in obj['data']:
            constituent_lookup_id = int(obj['data']['lookup_id'])]
        constituent_bb_id_to_lookup_id[obj['bb_id'] = constituent_lookup_id
    
    logger.info('created map for constituent lookup ids')
    
    # for obj in BlackbaudMembership.objects.values('membership__category', 'data', 'standing'):
    for membership in BlackbaudMembership.objects.all():
        category = membership.membership.category
        standing = membership.standing
        if hasattr(membership, 'data') and 'members' in membership.data:
            members_set = membership.data['members']
            for member in members_set:
                if 'primary' in member:
                    member_is_primary = True if member['primary'] else False
                    # member_is_primary = bool(member['primary'])

                    constituent_lookup_id = constituent_bb_id_to_lookup_id.get(member['constituent_id'])

                    # classify primary and secondary members (constituents)
                    if constituent_lookup_id:
                        if standing.lower() == 'active':
                            if member_is_primary and category in CONSTITUENTS_MEMBERSHIP_CATEGORIES_PRIMARY:
                                main_members.append(constituent_lookup_id)
                            elif not member_is_primary and category in CONSTITUENTS_MEMBERSHIP_CATEGORIES_SECONDARY:
                                secondary_members.append(constituent_lookup_id)
                                
    logger.info('found main and secondary members')
    
    return main_members, secondary_members
```