From 5cb9b059f32a488f3a02e27bb17f560ed19d06ef Mon Sep 17 00:00:00 2001 From: labhvam5 <88420539+labhvam5@users.noreply.github.com> Date: Fri, 24 Nov 2023 12:09:29 +0530 Subject: [PATCH] import-projects-rework (#515) * Adding scheduling logic * lint fix * lint fix * fixing comments * import-projects-base * Import projects base imp (#519) * adding sub module changes * inital run changes * adding is_auto_sync_enabled as project property * minor changes * removing print statements * resolving comment for sub module * resolving comments * lint fixes * switching to master branch * adding app label * removing old code (#517) * removing old code * removing old test and lint fix * Adding projects test (#522) * Adding projects test * adding new test * addin exceptions test * lint fix for test * lint fixes * fyle_integrations_import latest master * adding schedule script * lint fix * rm sub module * add submodule * add submodule fetch --------- Co-authored-by: ashwin1111 --- .github/workflows/codecov.yml | 2 + .github/workflows/production_deployment.yml | 2 + .github/workflows/pytest.yml | 2 + .github/workflows/staging_deployment.yml | 2 + .gitmodules | 3 + apps/mappings/exceptions.py | 54 + apps/mappings/helpers.py | 17 +- apps/mappings/{queue.py => queues.py} | 47 +- apps/mappings/schedules.py | 42 + apps/mappings/signals.py | 7 +- apps/mappings/tasks.py | 70 - .../apis/advanced_configurations/triggers.py | 2 +- .../apis/export_settings/triggers.py | 2 +- .../apis/import_settings/triggers.py | 2 +- .../workspaces/apis/map_employees/triggers.py | 2 +- apps/workspaces/utils.py | 2 +- fyle_integrations_imports | 1 + fyle_qbo_api/settings.py | 1 + .../create-update-new-projects-import.py | 33 + sql/functions/delete-workspace.sql | 6 + .../reset_db_fixtures/reset_db.sql | 109 +- .../test_fyle_integrations_imports/helpers.py | 36 + .../test_modules/fixtures.py | 5997 +++++++++++++++++ .../test_modules/test_base.py | 173 + .../test_modules/test_projects.py | 205 + .../test_tasks.py | 45 + tests/test_mappings/test_exceptions.py | 109 + tests/test_mappings/test_queues.py | 16 + tests/test_mappings/test_schedules.py | 35 + tests/test_mappings/test_tasks.py | 53 +- tests/test_quickbooks_online/test_tasks.py | 2 +- 31 files changed, 6942 insertions(+), 137 deletions(-) create mode 100644 .gitmodules rename apps/mappings/{queue.py => queues.py} (71%) create mode 100644 apps/mappings/schedules.py create mode 160000 fyle_integrations_imports create mode 100644 scripts/python/create-update-new-projects-import.py create mode 100644 tests/test_fyle_integrations_imports/helpers.py create mode 100644 tests/test_fyle_integrations_imports/test_modules/fixtures.py create mode 100644 tests/test_fyle_integrations_imports/test_modules/test_base.py create mode 100644 tests/test_fyle_integrations_imports/test_modules/test_projects.py create mode 100644 tests/test_fyle_integrations_imports/test_tasks.py create mode 100644 tests/test_mappings/test_exceptions.py create mode 100644 tests/test_mappings/test_queues.py create mode 100644 tests/test_mappings/test_schedules.py diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index 07ff9103..c65b9ab2 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -13,6 +13,8 @@ jobs: environment: CI Environment steps: - uses: actions/checkout@v2 + with: + submodules: recursive - uses: satackey/action-docker-layer-caching@v0.0.11 continue-on-error: true - name: Bring up Services and Run Tests diff --git a/.github/workflows/production_deployment.yml b/.github/workflows/production_deployment.yml index f5e0df4e..4a2fe8b9 100644 --- a/.github/workflows/production_deployment.yml +++ b/.github/workflows/production_deployment.yml @@ -10,6 +10,8 @@ jobs: environment: Production steps: - uses: actions/checkout@v2 + with: + submodules: recursive - uses: satackey/action-docker-layer-caching@v0.0.11 continue-on-error: true - name: push to dockerhub diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index ffa333da..005e4ca4 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -10,6 +10,8 @@ jobs: environment: CI Environment steps: - uses: actions/checkout@v2 + with: + submodules: recursive - name: Bring up Services and test for token health run: | docker-compose -f docker-compose-pipeline.yml build diff --git a/.github/workflows/staging_deployment.yml b/.github/workflows/staging_deployment.yml index cd6e46c4..46a9286d 100644 --- a/.github/workflows/staging_deployment.yml +++ b/.github/workflows/staging_deployment.yml @@ -14,6 +14,8 @@ jobs: environment: Staging steps: - uses: actions/checkout@v2 + with: + submodules: recursive - uses: satackey/action-docker-layer-caching@v0.0.11 continue-on-error: true - name: push to dockerhub diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..4c6f4474 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "fyle_integrations_imports"] + path = fyle_integrations_imports + url = https://github.com/fylein/fyle_integrations_imports/ diff --git a/apps/mappings/exceptions.py b/apps/mappings/exceptions.py index dfb7e59c..3934a824 100644 --- a/apps/mappings/exceptions.py +++ b/apps/mappings/exceptions.py @@ -6,6 +6,7 @@ from qbosdk.exceptions import WrongParamsError as QBOWrongParamsError from apps.workspaces.models import QBOCredential +from fyle_integrations_imports.models import ImportLog logger = logging.getLogger(__name__) logger.level = logging.INFO @@ -50,3 +51,56 @@ def new_fn(workspace_id: int, *args): return new_fn return decorator + + +def handle_import_exceptions_v2(func): + def new_fn(expense_attribute_instance, *args): + import_log: ImportLog = args[0] + workspace_id = import_log.workspace_id + attribute_type = import_log.attribute_type + error = { + 'task': 'Import {0} to Fyle and Auto Create Mappings'.format(attribute_type), + 'workspace_id': workspace_id, + 'message': None, + 'response': None + } + try: + return func(expense_attribute_instance, *args) + except WrongParamsError as exception: + error['message'] = exception.message + error['response'] = exception.response + error['alert'] = True + import_log.status = 'FAILED' + + except InvalidTokenError: + error['message'] = 'Invalid Token for fyle' + error['alert'] = False + import_log.status = 'FAILED' + + except InternalServerError: + error['message'] = 'Internal server error while importing to Fyle' + error['alert'] = True + import_log.status = 'FAILED' + + except (QBOWrongParamsError, QBOInvalidTokenError, QBOCredential.DoesNotExist) as exception: + error['message'] = 'Invalid Token or QBO credentials does not exist workspace_id - {0}'.format(workspace_id) + error['alert'] = False + error['response'] = exception.__dict__ + import_log.status = 'FAILED' + + except Exception: + response = traceback.format_exc() + error['message'] = 'Something went wrong' + error['response'] = response + error['alert'] = False + import_log.status = 'FATAL' + + if error['alert']: + logger.error(error) + else: + logger.info(error) + + import_log.error_log = error + import_log.save() + + return new_fn diff --git a/apps/mappings/helpers.py b/apps/mappings/helpers.py index 8c7215bc..b8040ab2 100644 --- a/apps/mappings/helpers.py +++ b/apps/mappings/helpers.py @@ -11,9 +11,20 @@ def schedule_or_delete_fyle_import_tasks(configuration: WorkspaceGeneralSettings :param configuration: WorkspaceGeneralSettings Instance :return: None """ - project_mapping = MappingSetting.objects.filter(source_field='PROJECT', workspace_id=configuration.workspace_id).first() - if configuration.import_categories or configuration.import_items or (project_mapping and project_mapping.import_to_fyle) or configuration.import_vendors_as_merchants: + if configuration.import_categories or configuration.import_items or configuration.import_vendors_as_merchants: start_datetime = datetime.now() Schedule.objects.update_or_create(func='apps.mappings.tasks.auto_import_and_map_fyle_fields', args='{}'.format(configuration.workspace_id), defaults={'schedule_type': Schedule.MINUTES, 'minutes': 24 * 60, 'next_run': start_datetime}) - elif not configuration.import_categories and not configuration.import_items and not (project_mapping and project_mapping.import_to_fyle) and not configuration.import_vendors_as_merchants: + elif not configuration.import_categories and not configuration.import_items and not configuration.import_vendors_as_merchants: Schedule.objects.filter(func='apps.mappings.tasks.auto_import_and_map_fyle_fields', args='{}'.format(configuration.workspace_id)).delete() + + +def get_auto_sync_permission(mapping_setting: MappingSetting): + """ + Get the auto sync permission + :return: bool + """ + is_auto_sync_status_allowed = False + if (mapping_setting.destination_field == 'CUSTOMER' and mapping_setting.source_field == 'PROJECT') or mapping_setting.source_field == 'CATEGORY': + is_auto_sync_status_allowed = True + + return is_auto_sync_status_allowed diff --git a/apps/mappings/queue.py b/apps/mappings/queues.py similarity index 71% rename from apps/mappings/queue.py rename to apps/mappings/queues.py index f7186ebe..de5a30b0 100644 --- a/apps/mappings/queue.py +++ b/apps/mappings/queues.py @@ -5,7 +5,20 @@ from fyle_accounting_mappings.models import MappingSetting from apps.mappings.models import GeneralMapping -from apps.workspaces.models import WorkspaceGeneralSettings +from apps.workspaces.models import WorkspaceGeneralSettings, QBOCredential +from apps.mappings.helpers import get_auto_sync_permission +from fyle_integrations_imports.queues import chain_import_fields_to_fyle +from fyle_integrations_imports.dataclasses import TaskSetting + +SYNC_METHODS = { + 'ACCOUNT': 'accounts', + 'ITEM': 'items', + 'VENDOR': 'vendors', + 'DEPARTMENT': 'departments', + 'TAX_CODE': 'tax_codes', + 'CLASS': 'classes', + 'CUSTOMER': 'customers', +} def async_auto_create_expense_field_mapping(mapping_setting: MappingSetting): @@ -86,3 +99,35 @@ def schedule_auto_map_employees(employee_mapping_preference: str, workspace_id: def async_disable_category_for_items_mapping(workspace_id: int): async_task('apps.mappings.tasks.disable_category_for_items_mapping', workspace_id) + + +def construct_tasks_and_chain_import_fields_to_fyle(workspace_id): + """ + Chain import fields to Fyle + :param workspace_id: Workspace Id + """ + mapping_settings = MappingSetting.objects.filter(workspace_id=workspace_id, import_to_fyle=True) + credentials = QBOCredential.objects.get(workspace_id=workspace_id) + + task_settings: TaskSetting = { + 'import_tax': None, + 'import_vendors_as_merchants': None, + 'import_categories': None, + 'mapping_settings': [], + 'credentials': credentials, + 'sdk_connection_string': 'apps.quickbooks_online.utils.QBOConnector', + } + + # For now we are only adding PROJECTS support that is why we are hardcoding it + if mapping_settings: + for mapping_setting in mapping_settings: + if mapping_setting.source_field in ['PROJECT']: + task_settings['mapping_settings'].append({ + 'source_field': mapping_setting.source_field, + 'destination_field': mapping_setting.destination_field, + 'destination_sync_method': SYNC_METHODS[mapping_setting.destination_field], + 'is_auto_sync_enabled': get_auto_sync_permission(mapping_setting), + 'is_custom': False, + }) + + chain_import_fields_to_fyle(workspace_id, task_settings) diff --git a/apps/mappings/schedules.py b/apps/mappings/schedules.py new file mode 100644 index 00000000..ea063d16 --- /dev/null +++ b/apps/mappings/schedules.py @@ -0,0 +1,42 @@ +from datetime import datetime +from django_q.models import Schedule +from apps.workspaces.models import WorkspaceGeneralSettings +from fyle_accounting_mappings.models import MappingSetting + + +def schedule_or_delete_fyle_import_tasks(workspace_general_settings: WorkspaceGeneralSettings, mapping_setting_instance: MappingSetting = None): + """ + Schedule or delete Fyle import tasks based on the configuration. + :param configuration: Workspace Configuration Instance + :param instance: Mapping Setting Instance + :return: None + """ + task_to_be_scheduled = None + # Check if there is a task to be scheduled + if mapping_setting_instance and mapping_setting_instance.import_to_fyle: + task_to_be_scheduled = mapping_setting_instance + + if task_to_be_scheduled: + Schedule.objects.update_or_create( + func='apps.mappings.queues.construct_tasks_and_chain_import_fields_to_fyle', + args='{}'.format(workspace_general_settings.workspace_id), + defaults={ + 'schedule_type': Schedule.MINUTES, + 'minutes': 24 * 60, + 'next_run': datetime.now() + } + ) + return + + import_fields_count = MappingSetting.objects.filter( + import_to_fyle=True, + workspace_id=workspace_general_settings.workspace_id, + source_field__in=['PROJECT'] + ).count() + + # If the import fields count is 0, delete the schedule + if import_fields_count == 0: + Schedule.objects.filter( + func='apps.mappings.queues.construct_tasks_and_chain_import_fields_to_fyle', + args='{}'.format(workspace_general_settings.workspace_id) + ).delete() diff --git a/apps/mappings/signals.py b/apps/mappings/signals.py index 9c6fa1bf..3cbb4cc0 100644 --- a/apps/mappings/signals.py +++ b/apps/mappings/signals.py @@ -5,13 +5,14 @@ from django.dispatch import receiver from fyle_accounting_mappings.models import EmployeeMapping, Mapping, MappingSetting -from apps.mappings.helpers import schedule_or_delete_fyle_import_tasks -from apps.mappings.queue import ( +from apps.mappings.queues import ( async_auto_create_expense_field_mapping, schedule_cost_centers_creation, schedule_fyle_attributes_creation, ) from apps.mappings.tasks import upload_attributes_to_fyle +# TODO: Fix the naming convention when we remove the old schedule_or_delete_fyle_import_tasks import from helpers.py +from apps.mappings.schedules import schedule_or_delete_fyle_import_tasks as new_schedule_or_delete_fyle_import_tasks from apps.tasks.models import Error from apps.workspaces.apis.import_settings.triggers import ImportSettingsTrigger from apps.workspaces.models import WorkspaceGeneralSettings @@ -51,7 +52,7 @@ def run_post_mapping_settings_triggers(sender, instance: MappingSetting, **kwarg workspace_general_settings = WorkspaceGeneralSettings.objects.filter(workspace_id=instance.workspace_id).first() if instance.source_field == 'PROJECT': - schedule_or_delete_fyle_import_tasks(workspace_general_settings) + new_schedule_or_delete_fyle_import_tasks(workspace_general_settings, instance) if instance.source_field == 'COST_CENTER': schedule_cost_centers_creation(instance.import_to_fyle, int(instance.workspace_id)) diff --git a/apps/mappings/tasks.py b/apps/mappings/tasks.py index 4765858d..f7d1503b 100644 --- a/apps/mappings/tasks.py +++ b/apps/mappings/tasks.py @@ -142,54 +142,6 @@ def disable_or_enable_expense_attributes(source_field: str, destination_field: s return expense_attributes_ids -def create_fyle_projects_payload(projects: List[DestinationAttribute], existing_project_names: list, updated_projects: List[ExpenseAttribute] = None): - """ - Create Fyle Projects Payload from QBO Customer / Projects - :param projects: QBO Projects - :param existing_project_names: Existing Projects in Fyle - :return: Fyle Projects Payload - """ - payload = [] - existing_project_names = [project_name.lower() for project_name in existing_project_names] - if updated_projects: - for project in updated_projects: - destination_id_of_project = project.mapping.first().destination.destination_id - payload.append({'id': project.source_id, 'name': project.value, 'code': destination_id_of_project, 'description': 'Project - {0}, Id - {1}'.format(project.value, destination_id_of_project), 'is_enabled': project.active}) - else: - for project in projects: - if project.value.lower() not in existing_project_names: - payload.append({'name': project.value, 'code': project.destination_id, 'description': 'Project - {0}, Id - {1}'.format(project.value, project.destination_id), 'is_enabled': project.active}) - - return payload - - -def post_projects_in_batches(platform: PlatformConnector, workspace_id: int, destination_field: str): - existing_project_names = ExpenseAttribute.objects.filter(attribute_type='PROJECT', workspace_id=workspace_id).values_list('value', flat=True) - qbo_attributes_count = DestinationAttribute.objects.filter(attribute_type=destination_field, workspace_id=workspace_id).count() - - page_size = 200 - for offset in range(0, qbo_attributes_count, page_size): - limit = offset + page_size - paginated_qbo_attributes = DestinationAttribute.objects.filter(attribute_type=destination_field, workspace_id=workspace_id).order_by('value', 'id')[offset:limit] - - paginated_qbo_attributes = remove_duplicates(paginated_qbo_attributes) - - fyle_payload: List[Dict] = create_fyle_projects_payload(paginated_qbo_attributes, existing_project_names) - if fyle_payload: - platform.projects.post_bulk(fyle_payload) - platform.projects.sync() - - Mapping.bulk_create_mappings(paginated_qbo_attributes, 'PROJECT', destination_field, workspace_id) - - if destination_field == 'CUSTOMER': - project_ids_to_be_changed = disable_or_enable_expense_attributes('PROJECT', 'CUSTOMER', workspace_id) - if project_ids_to_be_changed: - expense_attributes = ExpenseAttribute.objects.filter(id__in=project_ids_to_be_changed) - fyle_payload: List[Dict] = create_fyle_projects_payload(projects=[], existing_project_names=[], updated_projects=expense_attributes) - platform.projects.post_bulk(fyle_payload) - platform.projects.sync() - - @handle_import_exceptions(task_name='Auto Create Tax Code Mappings') def auto_create_tax_codes_mappings(workspace_id: int): """ @@ -209,24 +161,6 @@ def auto_create_tax_codes_mappings(workspace_id: int): upload_tax_groups_to_fyle(platform, workspace_id) -@handle_import_exceptions(task_name='Auto Create Project Mappings') -def auto_create_project_mappings(workspace_id: int): - """ - Create Project Mappings - :return: mappings - """ - fyle_credentials: FyleCredential = FyleCredential.objects.get(workspace_id=workspace_id) - platform = PlatformConnector(fyle_credentials) - - platform.projects.sync() - - mapping_setting = MappingSetting.objects.get(source_field='PROJECT', workspace_id=workspace_id) - - sync_qbo_attribute(mapping_setting.destination_field, workspace_id) - - post_projects_in_batches(platform, workspace_id, mapping_setting.destination_field) - - def create_fyle_categories_payload(categories: List[DestinationAttribute], workspace_id: int, updated_categories: List[ExpenseAttribute] = None): """ Create Fyle Categories Payload from QBO Customer / Categories @@ -792,7 +726,6 @@ def auto_import_and_map_fyle_fields(workspace_id): Auto import and map fyle fields """ workspace_general_settings: WorkspaceGeneralSettings = WorkspaceGeneralSettings.objects.get(workspace_id=workspace_id) - project_mapping = MappingSetting.objects.filter(source_field='PROJECT', workspace_id=workspace_general_settings.workspace_id).first() chain = Chain() @@ -802,8 +735,5 @@ def auto_import_and_map_fyle_fields(workspace_id): if workspace_general_settings.import_categories or workspace_general_settings.import_items: chain.append('apps.mappings.tasks.auto_create_category_mappings', workspace_id) - if project_mapping and project_mapping.import_to_fyle: - chain.append('apps.mappings.tasks.auto_create_project_mappings', workspace_id) - if chain.length() > 0: chain.run() diff --git a/apps/workspaces/apis/advanced_configurations/triggers.py b/apps/workspaces/apis/advanced_configurations/triggers.py index 0b391e53..8fb6f393 100644 --- a/apps/workspaces/apis/advanced_configurations/triggers.py +++ b/apps/workspaces/apis/advanced_configurations/triggers.py @@ -1,6 +1,6 @@ import logging -from apps.mappings.queue import schedule_bill_payment_creation +from apps.mappings.queues import schedule_bill_payment_creation from apps.quickbooks_online.queue import schedule_qbo_objects_status_sync, schedule_reimbursements_sync from apps.workspaces.models import WorkspaceGeneralSettings from apps.workspaces.actions import post_to_integration_settings diff --git a/apps/workspaces/apis/export_settings/triggers.py b/apps/workspaces/apis/export_settings/triggers.py index 1a2c7ed9..6288625a 100644 --- a/apps/workspaces/apis/export_settings/triggers.py +++ b/apps/workspaces/apis/export_settings/triggers.py @@ -1,6 +1,6 @@ from typing import Dict -from apps.mappings.queue import async_disable_category_for_items_mapping +from apps.mappings.queues import async_disable_category_for_items_mapping from apps.workspaces.models import WorkspaceGeneralSettings diff --git a/apps/workspaces/apis/import_settings/triggers.py b/apps/workspaces/apis/import_settings/triggers.py index 2a36862f..2fffb89e 100644 --- a/apps/workspaces/apis/import_settings/triggers.py +++ b/apps/workspaces/apis/import_settings/triggers.py @@ -5,7 +5,7 @@ from apps.fyle.models import ExpenseGroupSettings from apps.mappings.helpers import schedule_or_delete_fyle_import_tasks -from apps.mappings.queue import ( +from apps.mappings.queues import ( async_disable_category_for_items_mapping, schedule_cost_centers_creation, schedule_fyle_attributes_creation, diff --git a/apps/workspaces/apis/map_employees/triggers.py b/apps/workspaces/apis/map_employees/triggers.py index 882041d5..c658b60f 100644 --- a/apps/workspaces/apis/map_employees/triggers.py +++ b/apps/workspaces/apis/map_employees/triggers.py @@ -1,4 +1,4 @@ -from apps.mappings.queue import schedule_auto_map_employees +from apps.mappings.queues import schedule_auto_map_employees from apps.workspaces.models import WorkspaceGeneralSettings diff --git a/apps/workspaces/utils.py b/apps/workspaces/utils.py index 5648547e..039cd9ae 100644 --- a/apps/workspaces/utils.py +++ b/apps/workspaces/utils.py @@ -9,7 +9,7 @@ from qbosdk import InternalServerError, NotFoundClientError, UnauthorizedClientError, WrongParamsError from apps.fyle.models import ExpenseGroupSettings -from apps.mappings.queue import ( +from apps.mappings.queues import ( schedule_auto_map_ccc_employees, schedule_auto_map_employees, schedule_bill_payment_creation, diff --git a/fyle_integrations_imports b/fyle_integrations_imports new file mode 160000 index 00000000..ff3f581c --- /dev/null +++ b/fyle_integrations_imports @@ -0,0 +1 @@ +Subproject commit ff3f581cc29c4f533d4fb4632b049d785e4240c3 diff --git a/fyle_qbo_api/settings.py b/fyle_qbo_api/settings.py index 970e9477..05d7b262 100644 --- a/fyle_qbo_api/settings.py +++ b/fyle_qbo_api/settings.py @@ -44,6 +44,7 @@ 'corsheaders', 'fyle_rest_auth', 'fyle_accounting_mappings', + 'fyle_integrations_imports', 'django_q', 'django_filters', # User Created Apps diff --git a/scripts/python/create-update-new-projects-import.py b/scripts/python/create-update-new-projects-import.py new file mode 100644 index 00000000..d9da1a2b --- /dev/null +++ b/scripts/python/create-update-new-projects-import.py @@ -0,0 +1,33 @@ +from django.db import transaction +from datetime import datetime +from django_q.models import Schedule +from apps.workspaces.models import WorkspaceGeneralSettings +from fyle_accounting_mappings.models import MappingSetting +existing_import_enabled_schedules = Schedule.objects.filter( + func__in=['apps.mappings.tasks.auto_import_and_map_fyle_fields'] +).values('args') +try: + # Create/update new schedules in a transaction block + with transaction.atomic(): + for schedule in existing_import_enabled_schedules: + configuration = WorkspaceGeneralSettings.objects.get(workspace_id=schedule['args']) + mapping_setting = MappingSetting.objects.filter(source_field='PROJECT', workspace_id=schedule['args'], import_to_fyle=True).first() + if not configuration.import_categories and not configuration.import_vendors_as_merchants: + print('Deleting schedule for workspace_id: ', schedule['args']) + Schedule.objects.get( + func='apps.mappings.tasks.auto_import_and_map_fyle_fields', + args=schedule['args'] + ).delete() + if mapping_setting: + print('Creating schedule for workspace_id: ', schedule['args']) + Schedule.objects.create( + func='apps.mappings.queues.construct_tasks_and_chain_import_fields_to_fyle', + args=schedule['args'], + schedule_type= Schedule.MINUTES, + minutes=24 * 60, + next_run=datetime.now() + ) + # remove this sanity check after running this script + raise Exception("This is a sanity check") +except Exception as e: + print(e) diff --git a/sql/functions/delete-workspace.sql b/sql/functions/delete-workspace.sql index 175206f6..87c40fbb 100644 --- a/sql/functions/delete-workspace.sql +++ b/sql/functions/delete-workspace.sql @@ -25,6 +25,12 @@ BEGIN GET DIAGNOSTICS rcount = ROW_COUNT; RAISE NOTICE 'Deleted % errors', rcount; + DELETE + FROM import_logs il + WHERE il.workspace_id = _workspace_id; + GET DIAGNOSTICS rcount = ROW_COUNT; + RAISE NOTICE 'Deleted % import_logs', rcount; + DELETE FROM bill_lineitems bl WHERE bl.bill_id IN ( diff --git a/tests/sql_fixtures/reset_db_fixtures/reset_db.sql b/tests/sql_fixtures/reset_db_fixtures/reset_db.sql index 0c58638a..bd19fa08 100644 --- a/tests/sql_fixtures/reset_db_fixtures/reset_db.sql +++ b/tests/sql_fixtures/reset_db_fixtures/reset_db.sql @@ -3,7 +3,7 @@ -- -- Dumped from database version 15.4 (Debian 15.4-2.pgdg120+1) --- Dumped by pg_dump version 15.4 (Debian 15.4-2.pgdg100+1) +-- Dumped by pg_dump version 15.4 (Debian 15.4-2.pgdg120+1) SET statement_timeout = 0; SET lock_timeout = 0; @@ -1223,6 +1223,48 @@ CREATE TABLE public.general_mappings ( ALTER TABLE public.general_mappings OWNER TO postgres; +-- +-- Name: import_logs; Type: TABLE; Schema: public; Owner: postgres +-- + +CREATE TABLE public.import_logs ( + id integer NOT NULL, + attribute_type character varying(150) NOT NULL, + status character varying(255), + error_log jsonb NOT NULL, + total_batches_count integer NOT NULL, + processed_batches_count integer NOT NULL, + last_successful_run_at timestamp with time zone, + created_at timestamp with time zone NOT NULL, + updated_at timestamp with time zone NOT NULL, + workspace_id integer NOT NULL +); + + +ALTER TABLE public.import_logs OWNER TO postgres; + +-- +-- Name: import_logs_id_seq; Type: SEQUENCE; Schema: public; Owner: postgres +-- + +CREATE SEQUENCE public.import_logs_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER TABLE public.import_logs_id_seq OWNER TO postgres; + +-- +-- Name: import_logs_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: postgres +-- + +ALTER SEQUENCE public.import_logs_id_seq OWNED BY public.import_logs.id; + + -- -- Name: journal_entries; Type: TABLE; Schema: public; Owner: postgres -- @@ -2179,6 +2221,13 @@ ALTER TABLE ONLY public.fyle_credentials ALTER COLUMN id SET DEFAULT nextval('pu ALTER TABLE ONLY public.general_mappings ALTER COLUMN id SET DEFAULT nextval('public.mappings_generalmapping_id_seq'::regclass); +-- +-- Name: import_logs id; Type: DEFAULT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.import_logs ALTER COLUMN id SET DEFAULT nextval('public.import_logs_id_seq'::regclass); + + -- -- Name: journal_entries id; Type: DEFAULT; Schema: public; Owner: postgres -- @@ -2485,6 +2534,10 @@ COPY public.auth_permission (id, name, content_type_id, codename) FROM stdin; 178 Can change expense field 45 change_expensefield 179 Can delete expense field 45 delete_expensefield 180 Can view expense field 45 view_expensefield +181 Can add import log 46 add_importlog +182 Can change import log 46 change_importlog +183 Can delete import log 46 delete_importlog +184 Can view import log 46 view_importlog \. @@ -3733,6 +3786,7 @@ COPY public.django_content_type (id, app_label, model) FROM stdin; 43 workspaces lastexportdetail 44 fyle expensefilter 45 fyle_accounting_mappings expensefield +46 fyle_integrations_imports importlog \. @@ -3912,6 +3966,7 @@ COPY public.django_migrations (id, app, name, applied) FROM stdin; 169 fyle 0032_expense_accounting_export_summary 2023-09-04 09:16:33.110573+00 170 fyle 0033_expense_workspace 2023-09-05 12:23:23.807031+00 171 fyle 0034_expense_previous_export_state 2023-09-07 12:40:23.1024+00 +172 fyle_integrations_imports 0001_initial 2023-11-21 17:06:03.547973+00 \. @@ -33305,6 +33360,14 @@ COPY public.general_mappings (id, bank_account_name, bank_account_id, default_cc \. +-- +-- Data for Name: import_logs; Type: TABLE DATA; Schema: public; Owner: postgres +-- + +COPY public.import_logs (id, attribute_type, status, error_log, total_batches_count, processed_batches_count, last_successful_run_at, created_at, updated_at, workspace_id) FROM stdin; +\. + + -- -- Data for Name: journal_entries; Type: TABLE DATA; Schema: public; Owner: postgres -- @@ -33782,7 +33845,7 @@ SELECT pg_catalog.setval('public.auth_group_permissions_id_seq', 1, false); -- Name: auth_permission_id_seq; Type: SEQUENCE SET; Schema: public; Owner: postgres -- -SELECT pg_catalog.setval('public.auth_permission_id_seq', 180, true); +SELECT pg_catalog.setval('public.auth_permission_id_seq', 184, true); -- @@ -33817,14 +33880,14 @@ SELECT pg_catalog.setval('public.django_admin_log_id_seq', 1, false); -- Name: django_content_type_id_seq; Type: SEQUENCE SET; Schema: public; Owner: postgres -- -SELECT pg_catalog.setval('public.django_content_type_id_seq', 45, true); +SELECT pg_catalog.setval('public.django_content_type_id_seq', 46, true); -- -- Name: django_migrations_id_seq; Type: SEQUENCE SET; Schema: public; Owner: postgres -- -SELECT pg_catalog.setval('public.django_migrations_id_seq', 171, true); +SELECT pg_catalog.setval('public.django_migrations_id_seq', 172, true); -- @@ -33932,6 +33995,13 @@ SELECT pg_catalog.setval('public.fyle_expensegroupsettings_id_seq', 5, true); SELECT pg_catalog.setval('public.fyle_rest_auth_authtokens_id_seq', 1, true); +-- +-- Name: import_logs_id_seq; Type: SEQUENCE SET; Schema: public; Owner: postgres +-- + +SELECT pg_catalog.setval('public.import_logs_id_seq', 1, false); + + -- -- Name: last_export_details_id_seq; Type: SEQUENCE SET; Schema: public; Owner: postgres -- @@ -34407,6 +34477,22 @@ ALTER TABLE ONLY public.auth_tokens ADD CONSTRAINT fyle_rest_auth_authtokens_user_id_3b4bd82e_uniq UNIQUE (user_id); +-- +-- Name: import_logs import_logs_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.import_logs + ADD CONSTRAINT import_logs_pkey PRIMARY KEY (id); + + +-- +-- Name: import_logs import_logs_workspace_id_attribute_type_42f69b7b_uniq; Type: CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.import_logs + ADD CONSTRAINT import_logs_workspace_id_attribute_type_42f69b7b_uniq UNIQUE (workspace_id, attribute_type); + + -- -- Name: last_export_details last_export_details_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres -- @@ -34974,6 +35060,13 @@ CREATE INDEX fyle_expensegroup_expenses_expensegroup_id_1af76dce ON public.expen CREATE INDEX fyle_expensegroup_workspace_id_c9b3a8e4 ON public.expense_groups USING btree (workspace_id); +-- +-- Name: import_logs_workspace_id_e5acf2ff; Type: INDEX; Schema: public; Owner: postgres +-- + +CREATE INDEX import_logs_workspace_id_e5acf2ff ON public.import_logs USING btree (workspace_id); + + -- -- Name: mapping_settings_expense_field_id_e9afc6c2; Type: INDEX; Schema: public; Owner: postgres -- @@ -35363,6 +35456,14 @@ ALTER TABLE ONLY public.general_mappings ADD CONSTRAINT general_mappings_workspace_id_19666c5c_fk_workspaces_id FOREIGN KEY (workspace_id) REFERENCES public.workspaces(id) DEFERRABLE INITIALLY DEFERRED; +-- +-- Name: import_logs import_logs_workspace_id_e5acf2ff_fk_workspaces_id; Type: FK CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.import_logs + ADD CONSTRAINT import_logs_workspace_id_e5acf2ff_fk_workspaces_id FOREIGN KEY (workspace_id) REFERENCES public.workspaces(id) DEFERRABLE INITIALLY DEFERRED; + + -- -- Name: last_export_details last_export_details_workspace_id_0af72f0e_fk_workspaces_id; Type: FK CONSTRAINT; Schema: public; Owner: postgres -- diff --git a/tests/test_fyle_integrations_imports/helpers.py b/tests/test_fyle_integrations_imports/helpers.py new file mode 100644 index 00000000..8e710900 --- /dev/null +++ b/tests/test_fyle_integrations_imports/helpers.py @@ -0,0 +1,36 @@ +from fyle_integrations_imports.modules.base import Base +from fyle_integrations_platform_connector import PlatformConnector +from apps.workspaces.models import FyleCredential, QBOCredential +from apps.quickbooks_online.utils import QBOConnector + + +def get_base_class_instance( + workspace_id: int = 1, + source_field: str = 'PROJECT', + destination_field: str = 'PROJECT', + platform_class_name: str = 'projects', + sync_after: str = None, + destination_sync_method: str = 'customers' + ): + + qbo_credentials = QBOCredential.get_active_qbo_credentials(workspace_id) + qbo_connection = QBOConnector(credentials_object=qbo_credentials, workspace_id=workspace_id) + + base = Base( + workspace_id = workspace_id, + source_field = source_field, + destination_field = destination_field, + platform_class_name = platform_class_name, + sync_after = sync_after, + sdk_connection = qbo_connection, + destination_sync_method = destination_sync_method + ) + + return base + + +def get_platform_connection(workspace_id): + fyle_credentials = FyleCredential.objects.get(workspace_id=workspace_id) + platform = PlatformConnector(fyle_credentials=fyle_credentials) + + return platform diff --git a/tests/test_fyle_integrations_imports/test_modules/fixtures.py b/tests/test_fyle_integrations_imports/test_modules/fixtures.py new file mode 100644 index 00000000..9db05979 --- /dev/null +++ b/tests/test_fyle_integrations_imports/test_modules/fixtures.py @@ -0,0 +1,5997 @@ +projects_data = { + "create_new_auto_create_projects_destination_attributes": [ + { + 'Taxable':True, + 'BillAddr':{ + 'Id':'106' + }, + 'ShipAddr':{ + 'Id':'106' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'188', + 'SyncToken':'0', + 'MetaData':{ + 'CreateTime':'2023-05-31T00:26:45-07:00', + 'LastUpdatedTime':'2023-05-31T00:26:45-07:00' + }, + 'FullyQualifiedName':'1047 S Ocean Blvd', + 'CompanyName':'1047 S Ocean Blvd', + 'DisplayName':'1047 S Ocean Blvd', + 'PrintOnCheckName':'1047 S Ocean Blvd', + 'Active':True + }, + { + 'Taxable':True, + 'BillAddr':{ + 'Id':'108' + }, + 'ShipAddr':{ + 'Id':'108' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'190', + 'SyncToken':'4', + 'MetaData':{ + 'CreateTime':'2023-05-31T00:59:38-07:00', + 'LastUpdatedTime':'2023-11-16T04:44:58-08:00' + }, + 'FullyQualifiedName':'12 - Project 1', + 'DisplayName':'12 - Project 1', + 'PrintOnCheckName':'12 - Project 1', + 'Active':True + }, + { + 'Taxable':True, + 'BillAddr':{ + 'Id':'2', + 'Line1':'4581 Finch St.', + 'City':'Bayshore', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94326', + 'Lat':'INVALID', + 'Long':'INVALID' + }, + 'ShipAddr':{ + 'Id':'2', + 'Line1':'4581 Finch St.', + 'City':'Bayshore', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94326', + 'Lat':'INVALID', + 'Long':'INVALID' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':239.0, + 'BalanceWithJobs':239.0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'1', + 'SyncToken':'0', + 'MetaData':{ + 'CreateTime':'2019-12-11T16:48:43-08:00', + 'LastUpdatedTime':'2020-11-16T21:26:20-08:00' + }, + 'GivenName':'Amy', + 'FamilyName':'Lauterbach', + 'FullyQualifiedName':"Amy's Bird Sanctuary", + 'CompanyName':"Amy's Bird Sanctuary", + 'DisplayName':"Amy's Bird Sanctuary", + 'PrintOnCheckName':"Amy's Bird Sanctuary", + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(650) 555-3311' + }, + 'PrimaryEmailAddr':{ + 'Address':'Birds@Intuit.com' + } + }, + { + 'Taxable':False, + 'Job':True, + 'BillWithParent':True, + 'ParentRef':{ + 'value':'1' + }, + 'Level':1, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'58', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2020-11-16T21:26:20-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'FullyQualifiedName':"Amy's Bird Sanctuary:Test Project", + 'DisplayName':'Test Project', + 'PrintOnCheckName':'Test Project', + 'Active':True + }, + { + 'Taxable':True, + 'BillAddr':{ + 'Id':'107' + }, + 'ShipAddr':{ + 'Id':'107' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'189', + 'SyncToken':'4', + 'MetaData':{ + 'CreateTime':'2023-05-31T00:32:06-07:00', + 'LastUpdatedTime':'2023-11-16T03:52:43-08:00' + }, + 'FullyQualifiedName':'Ashu Staging', + 'DisplayName':'Ashu Staging', + 'PrintOnCheckName':'Ashu Staging', + 'Active':True + }, + { + 'Taxable':True, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'103', + 'SyncToken':'2', + 'MetaData':{ + 'CreateTime':'2021-04-12T22:38:46-07:00', + 'LastUpdatedTime':'2021-05-05T00:43:46-07:00' + }, + 'GivenName':'Ashwinn', + 'FullyQualifiedName':'Ashwinn', + 'DisplayName':'Ashwinn', + 'PrintOnCheckName':'Ashwinn', + 'Active':True, + 'DefaultTaxCodeRef':{ + 'value':'2' + } + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'3', + 'Line1':'12 Ocean Dr.', + 'City':'Half Moon Bay', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94213', + 'Lat':'37.4307072', + 'Long':'-122.4295234' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':85.0, + 'BalanceWithJobs':85.0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'2', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T16:49:28-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Bill', + 'FamilyName':'Lucchini', + 'FullyQualifiedName':"Bill's Windsurf Shop", + 'CompanyName':"Bill's Windsurf Shop", + 'DisplayName':"Bill's Windsurf Shop", + 'PrintOnCheckName':"Bill's Windsurf Shop", + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(415) 444-6538' + }, + 'PrimaryEmailAddr':{ + 'Address':'Surf@Intuit.com' + } + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'4', + 'Line1':'65 Ocean Dr.', + 'City':'Half Moon Bay', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94213', + 'Lat':'37.4300318', + 'Long':'-122.4336537' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'3', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T16:51:22-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Grace', + 'FamilyName':'Pariente', + 'FullyQualifiedName':'Cool Cars', + 'CompanyName':'Cool Cars', + 'DisplayName':'Cool Cars', + 'PrintOnCheckName':'Cool Cars', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(415) 555-9933' + }, + 'PrimaryEmailAddr':{ + 'Address':'Cool_Cars@intuit.com' + } + }, + { + 'Taxable':True, + 'BillAddr':{ + 'Id':'105' + }, + 'ShipAddr':{ + 'Id':'105' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'136', + 'SyncToken':'2', + 'MetaData':{ + 'CreateTime':'2022-08-11T02:11:19-07:00', + 'LastUpdatedTime':'2022-08-11T02:16:40-07:00' + }, + 'FullyQualifiedName':'Cred Technologies', + 'CompanyName':'Cred Technologies', + 'DisplayName':'Cred Technologies', + 'PrintOnCheckName':'Cred Technologies', + 'Active':True + }, + { + 'Taxable':True, + 'BillAddr':{ + 'Id':'111' + }, + 'ShipAddr':{ + 'Id':'111' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'235', + 'SyncToken':'2', + 'MetaData':{ + 'CreateTime':'2023-11-19T00:02:16-08:00', + 'LastUpdatedTime':'2023-11-19T00:07:02-08:00' + }, + 'FullyQualifiedName':'David', + 'CompanyName':'David', + 'DisplayName':'David', + 'PrintOnCheckName':'David', + 'Active':True + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'5', + 'Line1':'321 Channing', + 'City':'Palo Alto', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94303', + 'Lat':'37.443231', + 'Long':'-122.1561846' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'4', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T16:52:08-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Diego', + 'FamilyName':'Rodriguez', + 'FullyQualifiedName':'Diego Rodriguez', + 'DisplayName':'Diego Rodriguez', + 'PrintOnCheckName':'Diego Rodriguez', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(650) 555-4477' + }, + 'PrimaryEmailAddr':{ + 'Address':'Diego@Rodriguez.com' + } + }, + { + 'Taxable':False, + 'Job':True, + 'BillWithParent':True, + 'ParentRef':{ + 'value':'4' + }, + 'Level':1, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'59', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2020-11-16T21:26:43-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'FullyQualifiedName':'Diego Rodriguez:Test Project', + 'DisplayName':'Test Project', + 'PrintOnCheckName':'Test Project', + 'Active':True + }, + { + 'Taxable':True, + 'BillAddr':{ + 'Id':'6', + 'Line1':'25 Court St.', + 'City':'Tucson', + 'CountrySubDivisionCode':'AZ', + 'PostalCode':'85719', + 'Lat':'32.2841116', + 'Long':'-110.9744298' + }, + 'ShipAddr':{ + 'Id':'6', + 'Line1':'25 Court St.', + 'City':'Tucson', + 'CountrySubDivisionCode':'AZ', + 'PostalCode':'85719', + 'Lat':'32.2841116', + 'Long':'-110.9744298' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'5', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T16:54:59-08:00', + 'LastUpdatedTime':'2019-12-18T13:28:29-08:00' + }, + 'GivenName':'Peter', + 'FamilyName':'Dukes', + 'FullyQualifiedName':'Dukes Basketball Camp', + 'CompanyName':'Dukes Basketball Camp', + 'DisplayName':'Dukes Basketball Camp', + 'PrintOnCheckName':'Dukes Basketball Camp', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(520) 420-5638' + }, + 'PrimaryEmailAddr':{ + 'Address':'Dukes_bball@intuit.com' + } + }, + { + 'Taxable':False, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'6', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T16:55:21-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Dylan', + 'FamilyName':'Sollfrank', + 'FullyQualifiedName':'Dylan Sollfrank', + 'DisplayName':'Dylan Sollfrank', + 'PrintOnCheckName':'Dylan Sollfrank', + 'Active':True + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'7', + 'Line1':'370 Easy St.', + 'City':'Middlefield', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94482', + 'Lat':'37.4031672', + 'Long':'-122.0642815' + }, + 'ShipAddr':{ + 'Id':'7', + 'Line1':'370 Easy St.', + 'City':'Middlefield', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94482', + 'Lat':'37.4031672', + 'Long':'-122.0642815' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':562.5, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'7', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T16:57:10-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Kirby', + 'FamilyName':'Freeman', + 'FullyQualifiedName':'Freeman Sporting Goods', + 'CompanyName':'Freeman Sporting Goods', + 'DisplayName':'Freeman Sporting Goods', + 'PrintOnCheckName':'Freeman Sporting Goods', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(650) 555-0987' + }, + 'Mobile':{ + 'FreeFormNumber':'(973) 555-8849' + }, + 'Fax':{ + 'FreeFormNumber':'(520) 555-7894' + }, + 'PrimaryEmailAddr':{ + 'Address':'Sporting_goods@intuit.com' + }, + 'WebAddr':{ + 'URI':'http://sportinggoods.intuit.com' + } + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'8', + 'Line1':'370 Easy St.', + 'City':'Middlefield', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94482', + 'Lat':'37.4031672', + 'Long':'-122.0642815' + }, + 'ShipAddr':{ + 'Id':'8', + 'Line1':'370 Easy St.', + 'City':'Middlefield', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94482', + 'Lat':'37.4031672', + 'Long':'-122.0642815' + }, + 'Job':True, + 'BillWithParent':False, + 'ParentRef':{ + 'value':'7' + }, + 'Level':1, + 'Balance':477.5, + 'BalanceWithJobs':477.5, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'8', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T17:00:01-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Sasha', + 'FamilyName':'Tillou', + 'FullyQualifiedName':'Freeman Sporting Goods:0969 Ocean View Road', + 'CompanyName':'Freeman Sporting Goods', + 'DisplayName':'0969 Ocean View Road', + 'PrintOnCheckName':'Freeman Sporting Goods', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(415) 555-9933' + }, + 'Mobile':{ + 'FreeFormNumber':'(973) 555-8849' + }, + 'Fax':{ + 'FreeFormNumber':'(520) 555-7894' + }, + 'PrimaryEmailAddr':{ + 'Address':'Sporting_goods@intuit.com' + }, + 'WebAddr':{ + 'URI':'http://sportinggoods.intuit.com' + } + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'9', + 'Line1':'370 Easy St.', + 'City':'Middlefield', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94482', + 'Lat':'37.4031672', + 'Long':'-122.0642815' + }, + 'ShipAddr':{ + 'Id':'9', + 'Line1':'370 Easy St.', + 'City':'Middlefield', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94482', + 'Lat':'37.4031672', + 'Long':'-122.0642815' + }, + 'Job':True, + 'BillWithParent':False, + 'ParentRef':{ + 'value':'7' + }, + 'Level':1, + 'Balance':85.0, + 'BalanceWithJobs':85.0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'9', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T17:01:00-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Amelia', + 'FullyQualifiedName':'Freeman Sporting Goods:55 Twin Lane', + 'CompanyName':'Freeman Sporting Goods', + 'DisplayName':'55 Twin Lane', + 'PrintOnCheckName':'Freeman Sporting Goods', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(650) 555-0987' + }, + 'Mobile':{ + 'FreeFormNumber':'(973) 555-8849' + }, + 'Fax':{ + 'FreeFormNumber':'(520) 555-7894' + }, + 'PrimaryEmailAddr':{ + 'Address':'Sporting_goods@intuit.com' + }, + 'WebAddr':{ + 'URI':'http://sportinggoods.intuit.com' + } + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'10', + 'Line1':'1987 Main St.', + 'City':'Middlefield', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94303', + 'Lat':'37.445013', + 'Long':'-122.1391443' + }, + 'ShipAddr':{ + 'Id':'10', + 'Line1':'1987 Main St.', + 'City':'Middlefield', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94303', + 'Lat':'37.445013', + 'Long':'-122.1391443' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':629.1, + 'BalanceWithJobs':629.1, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'10', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T17:02:22-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Geeta', + 'FamilyName':'Kalapatapu', + 'FullyQualifiedName':'Geeta Kalapatapu', + 'DisplayName':'Geeta Kalapatapu', + 'PrintOnCheckName':'Geeta Kalapatapu', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(650) 555-0022' + }, + 'PrimaryEmailAddr':{ + 'Address':'Geeta@Kalapatapu.com' + } + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'11', + 'Line1':'1045 Main St.', + 'City':'Half Moon Bay', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94213', + 'Lat':'37.4559621', + 'Long':'-122.429939' + }, + 'ShipAddr':{ + 'Id':'11', + 'Line1':'1045 Main St.', + 'City':'Half Moon Bay', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94213', + 'Lat':'37.4559621', + 'Long':'-122.429939' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'11', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T17:04:02-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Lisa', + 'FamilyName':'Gevelber', + 'FullyQualifiedName':'Gevelber Photography', + 'CompanyName':'Gevelber Photography', + 'DisplayName':'Gevelber Photography', + 'PrintOnCheckName':'Gevelber Photography', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(415) 222-4345' + }, + 'PrimaryEmailAddr':{ + 'Address':'Photography@intuit.com' + }, + 'WebAddr':{ + 'URI':'http://gevelberphotography.com' + } + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'12', + 'Line1':'12 Willow Rd.', + 'City':'Menlo Park', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94305', + 'Lat':'37.4495308', + 'Long':'-122.1726923' + }, + 'ShipAddr':{ + 'Id':'12', + 'Line1':'12 Willow Rd.', + 'City':'Menlo Park', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94305', + 'Lat':'37.4495308', + 'Long':'-122.1726923' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':81.0, + 'BalanceWithJobs':81.0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'12', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T17:05:09-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Jeff', + 'FamilyName':'Chin', + 'FullyQualifiedName':"Jeff's Jalopies", + 'CompanyName':"Jeff's Jalopies", + 'DisplayName':"Jeff's Jalopies", + 'PrintOnCheckName':"Jeff's Jalopies", + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(650) 555-8989' + }, + 'PrimaryEmailAddr':{ + 'Address':'Jalopies@intuit.com' + } + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'13', + 'Line1':'85 Pine St.', + 'City':'Menlo Park', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94304', + 'Lat':'37.4451342', + 'Long':'-122.1409626' + }, + 'ShipAddr':{ + 'Id':'13', + 'Line1':'85 Pine St.', + 'City':'Menlo Park', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94304', + 'Lat':'37.4451342', + 'Long':'-122.1409626' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':450.0, + 'BalanceWithJobs':450.0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'13', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T17:06:42-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'John', + 'FamilyName':'Melton', + 'FullyQualifiedName':'John Melton', + 'DisplayName':'John Melton', + 'PrintOnCheckName':'John Melton', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(650) 555-5879' + }, + 'PrimaryEmailAddr':{ + 'Address':'John@Melton.com' + } + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'14', + 'Line1':'45 First St.', + 'City':'Menlo Park', + 'Country':'USA', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94304', + 'Lat':'37.4585825', + 'Long':'-122.1352789' + }, + 'ShipAddr':{ + 'Id':'14', + 'Line1':'45 First St.', + 'City':'Menlo Park', + 'Country':'USA', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94304', + 'Lat':'37.4585825', + 'Long':'-122.1352789' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'14', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T17:08:02-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Kate', + 'FamilyName':'Whelan', + 'FullyQualifiedName':'Kate Whelan', + 'DisplayName':'Kate Whelan', + 'PrintOnCheckName':'Kate Whelan', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(650) 554-8822' + }, + 'PrimaryEmailAddr':{ + 'Address':'Kate@Whelan.com' + } + }, + { + 'Taxable':True, + 'BillAddr':{ + 'Id':'109' + }, + 'ShipAddr':{ + 'Id':'109' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'233', + 'SyncToken':'2', + 'MetaData':{ + 'CreateTime':'2023-11-16T03:37:17-08:00', + 'LastUpdatedTime':'2023-11-16T03:43:26-08:00' + }, + 'FullyQualifiedName':'laysBlue', + 'CompanyName':'laysBlue', + 'DisplayName':'laysBlue', + 'PrintOnCheckName':'laysBlue', + 'Active':True + }, + { + 'Taxable':True, + 'BillAddr':{ + 'Id':'110' + }, + 'ShipAddr':{ + 'Id':'110' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'234', + 'SyncToken':'0', + 'MetaData':{ + 'CreateTime':'2023-11-16T03:37:34-08:00', + 'LastUpdatedTime':'2023-11-16T03:37:34-08:00' + }, + 'FullyQualifiedName':'laysRed', + 'CompanyName':'laysRed', + 'DisplayName':'laysRed', + 'PrintOnCheckName':'laysRed', + 'Active':True + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'17', + 'Line1':'36 Willow Rd', + 'City':'Menlo Park', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94304', + 'Lat':'37.450412', + 'Long':'-122.170593' + }, + 'ShipAddr':{ + 'Id':'17', + 'Line1':'36 Willow Rd', + 'City':'Menlo Park', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94304', + 'Lat':'37.450412', + 'Long':'-122.170593' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':314.28, + 'BalanceWithJobs':314.28, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'17', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T17:12:16-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Mark', + 'FamilyName':'Cho', + 'FullyQualifiedName':'Mark Cho', + 'DisplayName':'Mark Cho', + 'PrintOnCheckName':'Mark Cho', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(650) 554-1479' + }, + 'PrimaryEmailAddr':{ + 'Address':'Mark@Cho.com' + } + }, + { + 'Taxable':True, + 'BillAddr':{ + 'Id':'102' + }, + 'ShipAddr':{ + 'Id':'102' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'133', + 'SyncToken':'0', + 'MetaData':{ + 'CreateTime':'2022-07-26T23:06:54-07:00', + 'LastUpdatedTime':'2022-07-26T23:06:54-07:00' + }, + 'FullyQualifiedName':'naruto uzumaki', + 'DisplayName':'naruto uzumaki', + 'PrintOnCheckName':'naruto uzumaki', + 'Active':True + }, + { + 'Taxable':True, + 'BillAddr':{ + 'Id':'104' + }, + 'ShipAddr':{ + 'Id':'104' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'135', + 'SyncToken':'2', + 'MetaData':{ + 'CreateTime':'2022-08-11T02:03:08-07:00', + 'LastUpdatedTime':'2022-08-11T02:10:11-07:00' + }, + 'FullyQualifiedName':'New Inactive boi', + 'DisplayName':'New Inactive boi', + 'PrintOnCheckName':'New Inactive boi', + 'Active':True + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'15', + 'Line1':'350 Mountain View Dr.', + 'City':'South Orange', + 'CountrySubDivisionCode':'NJ', + 'PostalCode':'07079', + 'Lat':'40.7633073', + 'Long':'-74.2426072' + }, + 'ShipAddr':{ + 'Id':'15', + 'Line1':'350 Mountain View Dr.', + 'City':'South Orange', + 'CountrySubDivisionCode':'NJ', + 'PostalCode':'07079', + 'Lat':'40.7633073', + 'Long':'-74.2426072' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'15', + 'SyncToken':'2', + 'MetaData':{ + 'CreateTime':'2019-12-11T17:10:24-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Karen', + 'FamilyName':'Pye', + 'FullyQualifiedName':"Pye's Cakes", + 'CompanyName':"Pye's Cakes", + 'DisplayName':"Pye's Cakes", + 'PrintOnCheckName':"Pye's Cakes", + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(973) 555-4652' + }, + 'Mobile':{ + 'FreeFormNumber':'(973) 555-2234' + }, + 'PrimaryEmailAddr':{ + 'Address':'pyescakes@intuit.com' + }, + 'WebAddr':{ + 'URI':'http://www.pyescakes.intuit.com' + } + }, + { + 'Taxable':True, + 'BillAddr':{ + 'Id':'113' + }, + 'ShipAddr':{ + 'Id':'113' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'237', + 'SyncToken':'0', + 'MetaData':{ + 'CreateTime':'2023-11-19T00:09:19-08:00', + 'LastUpdatedTime':'2023-11-19T00:09:19-08:00' + }, + 'FullyQualifiedName':'Qwin', + 'CompanyName':'Qwin', + 'DisplayName':'Qwin', + 'PrintOnCheckName':'Qwin', + 'Active':True + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'20', + 'Line1':'753 Cedar St.', + 'City':'Bayshore', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94326', + 'Lat':'37.7077016', + 'Long':'-122.4273232' + }, + 'ShipAddr':{ + 'Id':'20', + 'Line1':'753 Cedar St.', + 'City':'Bayshore', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94326', + 'Lat':'37.7077016', + 'Long':'-122.4273232' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'19', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T17:14:24-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Jeff', + 'FamilyName':'Rago', + 'FullyQualifiedName':'Rago Travel Agency', + 'CompanyName':'Rago Travel Agency', + 'DisplayName':'Rago Travel Agency', + 'PrintOnCheckName':'Rago Travel Agency', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(650) 555-1596' + }, + 'PrimaryEmailAddr':{ + 'Address':'Rago_Travel@intuit.com' + } + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'21', + 'Line1':'500 Red Rock Rd.', + 'City':'Bayshore', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94326', + 'Lat':'INVALID', + 'Long':'INVALID' + }, + 'ShipAddr':{ + 'Id':'21', + 'Line1':'500 Red Rock Rd.', + 'City':'Bayshore', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94326', + 'Lat':'INVALID', + 'Long':'INVALID' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':226.0, + 'BalanceWithJobs':226.0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'20', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T17:15:14-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Stephanie', + 'FamilyName':'Martini', + 'FullyQualifiedName':'Red Rock Diner', + 'CompanyName':'Red Rock Diner', + 'DisplayName':'Red Rock Diner', + 'PrintOnCheckName':'Red Rock Diner', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(650) 555-4973' + }, + 'PrimaryEmailAddr':{ + 'Address':'qbwebsamplecompany@yahoo.com' + } + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'22', + 'Line1':'847 California Ave.', + 'City':'San Jose', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'95021', + 'Lat':'37.3313585', + 'Long':'-121.911372' + }, + 'ShipAddr':{ + 'Id':'22', + 'Line1':'847 California Ave.', + 'City':'San Jose', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'95021', + 'Lat':'37.3313585', + 'Long':'-121.911372' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':78.6, + 'BalanceWithJobs':78.6, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'21', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T17:17:21-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Rondonuwu', + 'MiddleName':'Fruit', + 'FamilyName':'and Vegi', + 'FullyQualifiedName':'Rondonuwu Fruit and Vegi', + 'DisplayName':'Rondonuwu Fruit and Vegi', + 'PrintOnCheckName':'Rondonuwu Fruit and Vegi', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(650) 555-2645' + }, + 'PrimaryEmailAddr':{ + 'Address':'Tony@Rondonuwu.com' + } + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'23', + 'Line1':'77 University', + 'City':'Palo Alto', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94303', + 'Lat':'37.4431445', + 'Long':'-122.164443' + }, + 'ShipAddr':{ + 'Id':'23', + 'Line1':'77 University', + 'City':'Palo Alto', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94303', + 'Lat':'37.4431445', + 'Long':'-122.164443' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':274.5, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'22', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T17:18:34-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Shara', + 'FamilyName':'Barnett', + 'FullyQualifiedName':'Shara Barnett', + 'DisplayName':'Shara Barnett', + 'PrintOnCheckName':'Shara Barnett', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(650) 555-4563' + }, + 'PrimaryEmailAddr':{ + 'Address':'Shara@Barnett.com' + } + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'24', + 'Line1':'19 Main St.', + 'City':'Middlefield', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94303', + 'Lat':'37.445013', + 'Long':'-122.1391443' + }, + 'ShipAddr':{ + 'Id':'24', + 'Line1':'19 Main St.', + 'City':'Middlefield', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94303', + 'Lat':'37.445013', + 'Long':'-122.1391443' + }, + 'Job':True, + 'BillWithParent':False, + 'ParentRef':{ + 'value':'22' + }, + 'Level':1, + 'Balance':274.5, + 'BalanceWithJobs':274.5, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'23', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T17:22:41-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Shara', + 'FamilyName':'Barnett', + 'FullyQualifiedName':'Shara Barnett:Barnett Design', + 'CompanyName':'Barnett Design', + 'DisplayName':'Barnett Design', + 'PrintOnCheckName':'Barnett Design', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(650) 557-1289' + }, + 'PrimaryEmailAddr':{ + 'Address':'Design@intuit.com' + } + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'25', + 'Line1':'5647 Cypress Hill Ave.', + 'City':'Middlefield', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94303', + 'Lat':'37.4238562', + 'Long':'-122.1141681' + }, + 'ShipAddr':{ + 'Id':'25', + 'Line1':'5647 Cypress Hill Ave.', + 'City':'Middlefield', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94303', + 'Lat':'37.4238562', + 'Long':'-122.1141681' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':362.07, + 'BalanceWithJobs':362.07, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'24', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T17:23:24-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Russ', + 'FamilyName':'Sonnenschein', + 'FullyQualifiedName':'Sonnenschein Family Store', + 'CompanyName':'Sonnenschein Family Store', + 'DisplayName':'Sonnenschein Family Store', + 'PrintOnCheckName':'Sonnenschein Family Store', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(650) 557-8463' + }, + 'PrimaryEmailAddr':{ + 'Address':'Familiystore@intuit.com' + } + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'26', + 'Line1':'898 Elm St.', + 'City':'Maplewood', + 'CountrySubDivisionCode':'NJ', + 'PostalCode':'07040', + 'Lat':'40.7312816', + 'Long':'-74.2652908' + }, + 'ShipAddr':{ + 'Id':'26', + 'Line1':'898 Elm St.', + 'City':'Maplewood', + 'CountrySubDivisionCode':'NJ', + 'PostalCode':'07040', + 'Lat':'40.7312816', + 'Long':'-74.2652908' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':160.0, + 'BalanceWithJobs':160.0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'25', + 'SyncToken':'3', + 'MetaData':{ + 'CreateTime':'2019-12-11T17:24:26-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Katsuyuki', + 'FamilyName':'Yanagawa', + 'FullyQualifiedName':'Sushi by Katsuyuki', + 'CompanyName':'Sushi by Katsuyuki', + 'DisplayName':'Sushi by Katsuyuki', + 'PrintOnCheckName':'Sushi by Katsuyuki', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(505) 570-0147' + }, + 'PrimaryEmailAddr':{ + 'Address':'Sushi@intuit.com' + } + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'27', + 'Line1':'78 First St.', + 'City':'Monlo Park', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94304', + 'Lat':'37.4585825', + 'Long':'-122.1352789' + }, + 'ShipAddr':{ + 'Id':'27', + 'Line1':'78 First St.', + 'City':'Monlo Park', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94304', + 'Lat':'37.4585825', + 'Long':'-122.1352789' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':414.72, + 'BalanceWithJobs':414.72, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'26', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T17:25:08-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Travis', + 'FamilyName':'Waldron', + 'FullyQualifiedName':'Travis Waldron', + 'DisplayName':'Travis Waldron', + 'PrintOnCheckName':'Travis Waldron', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(650) 557-9977' + }, + 'PrimaryEmailAddr':{ + 'Address':'Travis@Waldron.com' + } + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'28', + 'Line1':'202 Main St.', + 'City':'Tucson', + 'CountrySubDivisionCode':'AZ', + 'PostalCode':'85704', + 'Lat':'32.2242351', + 'Long':'-110.9758242' + }, + 'ShipAddr':{ + 'Id':'28', + 'Line1':'202 Main St.', + 'City':'Tucson', + 'CountrySubDivisionCode':'AZ', + 'PostalCode':'85704', + 'Lat':'32.2242351', + 'Long':'-110.9758242' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'27', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T17:26:07-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Dan', + 'FamilyName':'Wilks', + 'FullyQualifiedName':'Video Games by Dan', + 'CompanyName':'Video Games by Dan', + 'DisplayName':'Video Games by Dan', + 'PrintOnCheckName':'Video Games by Dan', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(650) 555-3456' + }, + 'PrimaryEmailAddr':{ + 'Address':'Videogames@intuit.com' + } + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'29', + 'Line1':'135 Broadway', + 'City':'Menlo Park', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94304', + 'Lat':'37.4846734', + 'Long':'-122.1989488' + }, + 'ShipAddr':{ + 'Id':'29', + 'Line1':'135 Broadway', + 'City':'Menlo Park', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94304', + 'Lat':'37.4846734', + 'Long':'-122.1989488' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'28', + 'SyncToken':'9', + 'MetaData':{ + 'CreateTime':'2019-12-11T17:28:21-08:00', + 'LastUpdatedTime':'2022-08-26T05:36:17-07:00' + }, + 'GivenName':'Whitney', + 'FamilyName':'Brewer', + 'FullyQualifiedName':'Wedding Planning by Whitney', + 'CompanyName':'Wedding Planning by Whitney', + 'DisplayName':'Wedding Planning by Whitney', + 'PrintOnCheckName':'Wedding Planning by Whitney', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(650) 557-2473' + }, + 'PrimaryEmailAddr':{ + 'Address':'Dream_Wedding@intuit.com' + }, + 'WebAddr':{ + 'URI':'http://www.dreamwedding.intuit.com' + } + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'30', + 'Line1':'45612 Main St.', + 'City':'Bayshore', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94326', + 'Lat':'45.256574', + 'Long':'-66.0943698' + }, + 'ShipAddr':{ + 'Id':'30', + 'Line1':'45612 Main St.', + 'City':'Bayshore', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94326', + 'Lat':'45.256574', + 'Long':'-66.0943698' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':375.0, + 'BalanceWithJobs':375.0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'29', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T17:29:04-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Nicola', + 'FamilyName':'Weiskopf', + 'FullyQualifiedName':'Weiskopf Consulting', + 'CompanyName':'Weiskopf Consulting', + 'DisplayName':'Weiskopf Consulting', + 'PrintOnCheckName':'Weiskopf Consulting', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(650) 555-1423' + }, + 'PrimaryEmailAddr':{ + 'Address':'Consulting@intuit.com' + } + }, + { + 'Taxable':True, + 'BillAddr':{ + 'Id':'100' + }, + 'ShipAddr':{ + 'Id':'100' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'131', + 'SyncToken':'12', + 'MetaData':{ + 'CreateTime':'2022-07-26T04:23:18-07:00', + 'LastUpdatedTime':'2023-11-16T03:41:27-08:00' + }, + 'FullyQualifiedName':'wraith squad', + 'DisplayName':'wraith squad', + 'PrintOnCheckName':'wraith squad', + 'Active':True + } + ], + "create_new_auto_create_projects_destination_attributes_disable_case": [ + { + 'Taxable':True, + 'BillAddr':{ + 'Id':'106' + }, + 'ShipAddr':{ + 'Id':'106' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'188', + 'SyncToken':'0', + 'MetaData':{ + 'CreateTime':'2023-05-31T00:26:45-07:00', + 'LastUpdatedTime':'2023-05-31T00:26:45-07:00' + }, + 'FullyQualifiedName':'1047 S Ocean Blvd', + 'CompanyName':'1047 S Ocean Blvd', + 'DisplayName':'1047 S Ocean Blvd', + 'PrintOnCheckName':'1047 S Ocean Blvd', + 'Active':True + }, + { + 'Taxable':True, + 'BillAddr':{ + 'Id':'108' + }, + 'ShipAddr':{ + 'Id':'108' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'190', + 'SyncToken':'4', + 'MetaData':{ + 'CreateTime':'2023-05-31T00:59:38-07:00', + 'LastUpdatedTime':'2023-11-16T04:44:58-08:00' + }, + 'FullyQualifiedName':'12 - Project 1', + 'DisplayName':'12 - Project 1', + 'PrintOnCheckName':'12 - Project 1', + 'Active':True + }, + { + 'Taxable':True, + 'BillAddr':{ + 'Id':'2', + 'Line1':'4581 Finch St.', + 'City':'Bayshore', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94326', + 'Lat':'INVALID', + 'Long':'INVALID' + }, + 'ShipAddr':{ + 'Id':'2', + 'Line1':'4581 Finch St.', + 'City':'Bayshore', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94326', + 'Lat':'INVALID', + 'Long':'INVALID' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':239.0, + 'BalanceWithJobs':239.0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'1', + 'SyncToken':'0', + 'MetaData':{ + 'CreateTime':'2019-12-11T16:48:43-08:00', + 'LastUpdatedTime':'2020-11-16T21:26:20-08:00' + }, + 'GivenName':'Amy', + 'FamilyName':'Lauterbach', + 'FullyQualifiedName':"Amy's Bird Sanctuary", + 'CompanyName':"Amy's Bird Sanctuary", + 'DisplayName':"Amy's Bird Sanctuary", + 'PrintOnCheckName':"Amy's Bird Sanctuary", + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(650) 555-3311' + }, + 'PrimaryEmailAddr':{ + 'Address':'Birds@Intuit.com' + } + }, + { + 'Taxable':False, + 'Job':True, + 'BillWithParent':True, + 'ParentRef':{ + 'value':'1' + }, + 'Level':1, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'58', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2020-11-16T21:26:20-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'FullyQualifiedName':"Amy's Bird Sanctuary:Test Project", + 'DisplayName':'Test Project', + 'PrintOnCheckName':'Test Project', + 'Active':True + }, + { + 'Taxable':True, + 'BillAddr':{ + 'Id':'107' + }, + 'ShipAddr':{ + 'Id':'107' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'189', + 'SyncToken':'4', + 'MetaData':{ + 'CreateTime':'2023-05-31T00:32:06-07:00', + 'LastUpdatedTime':'2023-11-16T03:52:43-08:00' + }, + 'FullyQualifiedName':'Ashu Staging', + 'DisplayName':'Ashu Staging', + 'PrintOnCheckName':'Ashu Staging', + 'Active':True + }, + { + 'Taxable':True, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'103', + 'SyncToken':'2', + 'MetaData':{ + 'CreateTime':'2021-04-12T22:38:46-07:00', + 'LastUpdatedTime':'2021-05-05T00:43:46-07:00' + }, + 'GivenName':'Ashwinn', + 'FullyQualifiedName':'Ashwinn', + 'DisplayName':'Ashwinn', + 'PrintOnCheckName':'Ashwinn', + 'Active':True, + 'DefaultTaxCodeRef':{ + 'value':'2' + } + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'3', + 'Line1':'12 Ocean Dr.', + 'City':'Half Moon Bay', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94213', + 'Lat':'37.4307072', + 'Long':'-122.4295234' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':85.0, + 'BalanceWithJobs':85.0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'2', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T16:49:28-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Bill', + 'FamilyName':'Lucchini', + 'FullyQualifiedName':"Bill's Windsurf Shop", + 'CompanyName':"Bill's Windsurf Shop", + 'DisplayName':"Bill's Windsurf Shop", + 'PrintOnCheckName':"Bill's Windsurf Shop", + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(415) 444-6538' + }, + 'PrimaryEmailAddr':{ + 'Address':'Surf@Intuit.com' + } + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'4', + 'Line1':'65 Ocean Dr.', + 'City':'Half Moon Bay', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94213', + 'Lat':'37.4300318', + 'Long':'-122.4336537' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'3', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T16:51:22-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Grace', + 'FamilyName':'Pariente', + 'FullyQualifiedName':'Cool Cars', + 'CompanyName':'Cool Cars', + 'DisplayName':'Cool Cars', + 'PrintOnCheckName':'Cool Cars', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(415) 555-9933' + }, + 'PrimaryEmailAddr':{ + 'Address':'Cool_Cars@intuit.com' + } + }, + { + 'Taxable':True, + 'BillAddr':{ + 'Id':'105' + }, + 'ShipAddr':{ + 'Id':'105' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'136', + 'SyncToken':'2', + 'MetaData':{ + 'CreateTime':'2022-08-11T02:11:19-07:00', + 'LastUpdatedTime':'2022-08-11T02:16:40-07:00' + }, + 'FullyQualifiedName':'Cred Technologies', + 'CompanyName':'Cred Technologies', + 'DisplayName':'Cred Technologies', + 'PrintOnCheckName':'Cred Technologies', + 'Active':True + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'5', + 'Line1':'321 Channing', + 'City':'Palo Alto', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94303', + 'Lat':'37.443231', + 'Long':'-122.1561846' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'4', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T16:52:08-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Diego', + 'FamilyName':'Rodriguez', + 'FullyQualifiedName':'Diego Rodriguez', + 'DisplayName':'Diego Rodriguez', + 'PrintOnCheckName':'Diego Rodriguez', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(650) 555-4477' + }, + 'PrimaryEmailAddr':{ + 'Address':'Diego@Rodriguez.com' + } + }, + { + 'Taxable':False, + 'Job':True, + 'BillWithParent':True, + 'ParentRef':{ + 'value':'4' + }, + 'Level':1, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'59', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2020-11-16T21:26:43-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'FullyQualifiedName':'Diego Rodriguez:Test Project', + 'DisplayName':'Test Project', + 'PrintOnCheckName':'Test Project', + 'Active':True + }, + { + 'Taxable':True, + 'BillAddr':{ + 'Id':'6', + 'Line1':'25 Court St.', + 'City':'Tucson', + 'CountrySubDivisionCode':'AZ', + 'PostalCode':'85719', + 'Lat':'32.2841116', + 'Long':'-110.9744298' + }, + 'ShipAddr':{ + 'Id':'6', + 'Line1':'25 Court St.', + 'City':'Tucson', + 'CountrySubDivisionCode':'AZ', + 'PostalCode':'85719', + 'Lat':'32.2841116', + 'Long':'-110.9744298' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'5', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T16:54:59-08:00', + 'LastUpdatedTime':'2019-12-18T13:28:29-08:00' + }, + 'GivenName':'Peter', + 'FamilyName':'Dukes', + 'FullyQualifiedName':'Dukes Basketball Camp', + 'CompanyName':'Dukes Basketball Camp', + 'DisplayName':'Dukes Basketball Camp', + 'PrintOnCheckName':'Dukes Basketball Camp', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(520) 420-5638' + }, + 'PrimaryEmailAddr':{ + 'Address':'Dukes_bball@intuit.com' + } + }, + { + 'Taxable':False, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'6', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T16:55:21-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Dylan', + 'FamilyName':'Sollfrank', + 'FullyQualifiedName':'Dylan Sollfrank', + 'DisplayName':'Dylan Sollfrank', + 'PrintOnCheckName':'Dylan Sollfrank', + 'Active':True + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'7', + 'Line1':'370 Easy St.', + 'City':'Middlefield', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94482', + 'Lat':'37.4031672', + 'Long':'-122.0642815' + }, + 'ShipAddr':{ + 'Id':'7', + 'Line1':'370 Easy St.', + 'City':'Middlefield', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94482', + 'Lat':'37.4031672', + 'Long':'-122.0642815' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':562.5, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'7', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T16:57:10-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Kirby', + 'FamilyName':'Freeman', + 'FullyQualifiedName':'Freeman Sporting Goods', + 'CompanyName':'Freeman Sporting Goods', + 'DisplayName':'Freeman Sporting Goods', + 'PrintOnCheckName':'Freeman Sporting Goods', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(650) 555-0987' + }, + 'Mobile':{ + 'FreeFormNumber':'(973) 555-8849' + }, + 'Fax':{ + 'FreeFormNumber':'(520) 555-7894' + }, + 'PrimaryEmailAddr':{ + 'Address':'Sporting_goods@intuit.com' + }, + 'WebAddr':{ + 'URI':'http://sportinggoods.intuit.com' + } + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'8', + 'Line1':'370 Easy St.', + 'City':'Middlefield', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94482', + 'Lat':'37.4031672', + 'Long':'-122.0642815' + }, + 'ShipAddr':{ + 'Id':'8', + 'Line1':'370 Easy St.', + 'City':'Middlefield', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94482', + 'Lat':'37.4031672', + 'Long':'-122.0642815' + }, + 'Job':True, + 'BillWithParent':False, + 'ParentRef':{ + 'value':'7' + }, + 'Level':1, + 'Balance':477.5, + 'BalanceWithJobs':477.5, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'8', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T17:00:01-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Sasha', + 'FamilyName':'Tillou', + 'FullyQualifiedName':'Freeman Sporting Goods:0969 Ocean View Road', + 'CompanyName':'Freeman Sporting Goods', + 'DisplayName':'0969 Ocean View Road', + 'PrintOnCheckName':'Freeman Sporting Goods', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(415) 555-9933' + }, + 'Mobile':{ + 'FreeFormNumber':'(973) 555-8849' + }, + 'Fax':{ + 'FreeFormNumber':'(520) 555-7894' + }, + 'PrimaryEmailAddr':{ + 'Address':'Sporting_goods@intuit.com' + }, + 'WebAddr':{ + 'URI':'http://sportinggoods.intuit.com' + } + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'9', + 'Line1':'370 Easy St.', + 'City':'Middlefield', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94482', + 'Lat':'37.4031672', + 'Long':'-122.0642815' + }, + 'ShipAddr':{ + 'Id':'9', + 'Line1':'370 Easy St.', + 'City':'Middlefield', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94482', + 'Lat':'37.4031672', + 'Long':'-122.0642815' + }, + 'Job':True, + 'BillWithParent':False, + 'ParentRef':{ + 'value':'7' + }, + 'Level':1, + 'Balance':85.0, + 'BalanceWithJobs':85.0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'9', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T17:01:00-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Amelia', + 'FullyQualifiedName':'Freeman Sporting Goods:55 Twin Lane', + 'CompanyName':'Freeman Sporting Goods', + 'DisplayName':'55 Twin Lane', + 'PrintOnCheckName':'Freeman Sporting Goods', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(650) 555-0987' + }, + 'Mobile':{ + 'FreeFormNumber':'(973) 555-8849' + }, + 'Fax':{ + 'FreeFormNumber':'(520) 555-7894' + }, + 'PrimaryEmailAddr':{ + 'Address':'Sporting_goods@intuit.com' + }, + 'WebAddr':{ + 'URI':'http://sportinggoods.intuit.com' + } + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'10', + 'Line1':'1987 Main St.', + 'City':'Middlefield', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94303', + 'Lat':'37.445013', + 'Long':'-122.1391443' + }, + 'ShipAddr':{ + 'Id':'10', + 'Line1':'1987 Main St.', + 'City':'Middlefield', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94303', + 'Lat':'37.445013', + 'Long':'-122.1391443' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':629.1, + 'BalanceWithJobs':629.1, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'10', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T17:02:22-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Geeta', + 'FamilyName':'Kalapatapu', + 'FullyQualifiedName':'Geeta Kalapatapu', + 'DisplayName':'Geeta Kalapatapu', + 'PrintOnCheckName':'Geeta Kalapatapu', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(650) 555-0022' + }, + 'PrimaryEmailAddr':{ + 'Address':'Geeta@Kalapatapu.com' + } + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'11', + 'Line1':'1045 Main St.', + 'City':'Half Moon Bay', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94213', + 'Lat':'37.4559621', + 'Long':'-122.429939' + }, + 'ShipAddr':{ + 'Id':'11', + 'Line1':'1045 Main St.', + 'City':'Half Moon Bay', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94213', + 'Lat':'37.4559621', + 'Long':'-122.429939' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'11', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T17:04:02-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Lisa', + 'FamilyName':'Gevelber', + 'FullyQualifiedName':'Gevelber Photography', + 'CompanyName':'Gevelber Photography', + 'DisplayName':'Gevelber Photography', + 'PrintOnCheckName':'Gevelber Photography', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(415) 222-4345' + }, + 'PrimaryEmailAddr':{ + 'Address':'Photography@intuit.com' + }, + 'WebAddr':{ + 'URI':'http://gevelberphotography.com' + } + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'12', + 'Line1':'12 Willow Rd.', + 'City':'Menlo Park', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94305', + 'Lat':'37.4495308', + 'Long':'-122.1726923' + }, + 'ShipAddr':{ + 'Id':'12', + 'Line1':'12 Willow Rd.', + 'City':'Menlo Park', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94305', + 'Lat':'37.4495308', + 'Long':'-122.1726923' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':81.0, + 'BalanceWithJobs':81.0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'12', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T17:05:09-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Jeff', + 'FamilyName':'Chin', + 'FullyQualifiedName':"Jeff's Jalopies", + 'CompanyName':"Jeff's Jalopies", + 'DisplayName':"Jeff's Jalopies", + 'PrintOnCheckName':"Jeff's Jalopies", + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(650) 555-8989' + }, + 'PrimaryEmailAddr':{ + 'Address':'Jalopies@intuit.com' + } + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'13', + 'Line1':'85 Pine St.', + 'City':'Menlo Park', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94304', + 'Lat':'37.4451342', + 'Long':'-122.1409626' + }, + 'ShipAddr':{ + 'Id':'13', + 'Line1':'85 Pine St.', + 'City':'Menlo Park', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94304', + 'Lat':'37.4451342', + 'Long':'-122.1409626' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':450.0, + 'BalanceWithJobs':450.0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'13', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T17:06:42-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'John', + 'FamilyName':'Melton', + 'FullyQualifiedName':'John Melton', + 'DisplayName':'John Melton', + 'PrintOnCheckName':'John Melton', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(650) 555-5879' + }, + 'PrimaryEmailAddr':{ + 'Address':'John@Melton.com' + } + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'14', + 'Line1':'45 First St.', + 'City':'Menlo Park', + 'Country':'USA', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94304', + 'Lat':'37.4585825', + 'Long':'-122.1352789' + }, + 'ShipAddr':{ + 'Id':'14', + 'Line1':'45 First St.', + 'City':'Menlo Park', + 'Country':'USA', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94304', + 'Lat':'37.4585825', + 'Long':'-122.1352789' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'14', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T17:08:02-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Kate', + 'FamilyName':'Whelan', + 'FullyQualifiedName':'Kate Whelan', + 'DisplayName':'Kate Whelan', + 'PrintOnCheckName':'Kate Whelan', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(650) 554-8822' + }, + 'PrimaryEmailAddr':{ + 'Address':'Kate@Whelan.com' + } + }, + { + 'Taxable':True, + 'BillAddr':{ + 'Id':'109' + }, + 'ShipAddr':{ + 'Id':'109' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'233', + 'SyncToken':'2', + 'MetaData':{ + 'CreateTime':'2023-11-16T03:37:17-08:00', + 'LastUpdatedTime':'2023-11-16T03:43:26-08:00' + }, + 'FullyQualifiedName':'laysBlue', + 'CompanyName':'laysBlue', + 'DisplayName':'laysBlue', + 'PrintOnCheckName':'laysBlue', + 'Active':True + }, + { + 'Taxable':True, + 'BillAddr':{ + 'Id':'110' + }, + 'ShipAddr':{ + 'Id':'110' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'234', + 'SyncToken':'0', + 'MetaData':{ + 'CreateTime':'2023-11-16T03:37:34-08:00', + 'LastUpdatedTime':'2023-11-16T03:37:34-08:00' + }, + 'FullyQualifiedName':'laysRed', + 'CompanyName':'laysRed', + 'DisplayName':'laysRed', + 'PrintOnCheckName':'laysRed', + 'Active':True + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'17', + 'Line1':'36 Willow Rd', + 'City':'Menlo Park', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94304', + 'Lat':'37.450412', + 'Long':'-122.170593' + }, + 'ShipAddr':{ + 'Id':'17', + 'Line1':'36 Willow Rd', + 'City':'Menlo Park', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94304', + 'Lat':'37.450412', + 'Long':'-122.170593' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':314.28, + 'BalanceWithJobs':314.28, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'17', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T17:12:16-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Mark', + 'FamilyName':'Cho', + 'FullyQualifiedName':'Mark Cho', + 'DisplayName':'Mark Cho', + 'PrintOnCheckName':'Mark Cho', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(650) 554-1479' + }, + 'PrimaryEmailAddr':{ + 'Address':'Mark@Cho.com' + } + }, + { + 'Taxable':True, + 'BillAddr':{ + 'Id':'102' + }, + 'ShipAddr':{ + 'Id':'102' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'133', + 'SyncToken':'0', + 'MetaData':{ + 'CreateTime':'2022-07-26T23:06:54-07:00', + 'LastUpdatedTime':'2022-07-26T23:06:54-07:00' + }, + 'FullyQualifiedName':'naruto uzumaki', + 'DisplayName':'naruto uzumaki', + 'PrintOnCheckName':'naruto uzumaki', + 'Active':True + }, + { + 'Taxable':True, + 'BillAddr':{ + 'Id':'104' + }, + 'ShipAddr':{ + 'Id':'104' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'135', + 'SyncToken':'2', + 'MetaData':{ + 'CreateTime':'2022-08-11T02:03:08-07:00', + 'LastUpdatedTime':'2022-08-11T02:10:11-07:00' + }, + 'FullyQualifiedName':'New Inactive boi', + 'DisplayName':'New Inactive boi', + 'PrintOnCheckName':'New Inactive boi', + 'Active':True + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'15', + 'Line1':'350 Mountain View Dr.', + 'City':'South Orange', + 'CountrySubDivisionCode':'NJ', + 'PostalCode':'07079', + 'Lat':'40.7633073', + 'Long':'-74.2426072' + }, + 'ShipAddr':{ + 'Id':'15', + 'Line1':'350 Mountain View Dr.', + 'City':'South Orange', + 'CountrySubDivisionCode':'NJ', + 'PostalCode':'07079', + 'Lat':'40.7633073', + 'Long':'-74.2426072' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'15', + 'SyncToken':'2', + 'MetaData':{ + 'CreateTime':'2019-12-11T17:10:24-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Karen', + 'FamilyName':'Pye', + 'FullyQualifiedName':"Pye's Cakes", + 'CompanyName':"Pye's Cakes", + 'DisplayName':"Pye's Cakes", + 'PrintOnCheckName':"Pye's Cakes", + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(973) 555-4652' + }, + 'Mobile':{ + 'FreeFormNumber':'(973) 555-2234' + }, + 'PrimaryEmailAddr':{ + 'Address':'pyescakes@intuit.com' + }, + 'WebAddr':{ + 'URI':'http://www.pyescakes.intuit.com' + } + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'20', + 'Line1':'753 Cedar St.', + 'City':'Bayshore', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94326', + 'Lat':'37.7077016', + 'Long':'-122.4273232' + }, + 'ShipAddr':{ + 'Id':'20', + 'Line1':'753 Cedar St.', + 'City':'Bayshore', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94326', + 'Lat':'37.7077016', + 'Long':'-122.4273232' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'19', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T17:14:24-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Jeff', + 'FamilyName':'Rago', + 'FullyQualifiedName':'Rago Travel Agency', + 'CompanyName':'Rago Travel Agency', + 'DisplayName':'Rago Travel Agency', + 'PrintOnCheckName':'Rago Travel Agency', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(650) 555-1596' + }, + 'PrimaryEmailAddr':{ + 'Address':'Rago_Travel@intuit.com' + } + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'21', + 'Line1':'500 Red Rock Rd.', + 'City':'Bayshore', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94326', + 'Lat':'INVALID', + 'Long':'INVALID' + }, + 'ShipAddr':{ + 'Id':'21', + 'Line1':'500 Red Rock Rd.', + 'City':'Bayshore', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94326', + 'Lat':'INVALID', + 'Long':'INVALID' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':226.0, + 'BalanceWithJobs':226.0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'20', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T17:15:14-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Stephanie', + 'FamilyName':'Martini', + 'FullyQualifiedName':'Red Rock Diner', + 'CompanyName':'Red Rock Diner', + 'DisplayName':'Red Rock Diner', + 'PrintOnCheckName':'Red Rock Diner', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(650) 555-4973' + }, + 'PrimaryEmailAddr':{ + 'Address':'qbwebsamplecompany@yahoo.com' + } + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'22', + 'Line1':'847 California Ave.', + 'City':'San Jose', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'95021', + 'Lat':'37.3313585', + 'Long':'-121.911372' + }, + 'ShipAddr':{ + 'Id':'22', + 'Line1':'847 California Ave.', + 'City':'San Jose', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'95021', + 'Lat':'37.3313585', + 'Long':'-121.911372' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':78.6, + 'BalanceWithJobs':78.6, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'21', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T17:17:21-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Rondonuwu', + 'MiddleName':'Fruit', + 'FamilyName':'and Vegi', + 'FullyQualifiedName':'Rondonuwu Fruit and Vegi', + 'DisplayName':'Rondonuwu Fruit and Vegi', + 'PrintOnCheckName':'Rondonuwu Fruit and Vegi', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(650) 555-2645' + }, + 'PrimaryEmailAddr':{ + 'Address':'Tony@Rondonuwu.com' + } + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'23', + 'Line1':'77 University', + 'City':'Palo Alto', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94303', + 'Lat':'37.4431445', + 'Long':'-122.164443' + }, + 'ShipAddr':{ + 'Id':'23', + 'Line1':'77 University', + 'City':'Palo Alto', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94303', + 'Lat':'37.4431445', + 'Long':'-122.164443' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':274.5, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'22', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T17:18:34-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Shara', + 'FamilyName':'Barnett', + 'FullyQualifiedName':'Shara Barnett', + 'DisplayName':'Shara Barnett', + 'PrintOnCheckName':'Shara Barnett', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(650) 555-4563' + }, + 'PrimaryEmailAddr':{ + 'Address':'Shara@Barnett.com' + } + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'24', + 'Line1':'19 Main St.', + 'City':'Middlefield', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94303', + 'Lat':'37.445013', + 'Long':'-122.1391443' + }, + 'ShipAddr':{ + 'Id':'24', + 'Line1':'19 Main St.', + 'City':'Middlefield', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94303', + 'Lat':'37.445013', + 'Long':'-122.1391443' + }, + 'Job':True, + 'BillWithParent':False, + 'ParentRef':{ + 'value':'22' + }, + 'Level':1, + 'Balance':274.5, + 'BalanceWithJobs':274.5, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'23', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T17:22:41-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Shara', + 'FamilyName':'Barnett', + 'FullyQualifiedName':'Shara Barnett:Barnett Design', + 'CompanyName':'Barnett Design', + 'DisplayName':'Barnett Design', + 'PrintOnCheckName':'Barnett Design', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(650) 557-1289' + }, + 'PrimaryEmailAddr':{ + 'Address':'Design@intuit.com' + } + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'25', + 'Line1':'5647 Cypress Hill Ave.', + 'City':'Middlefield', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94303', + 'Lat':'37.4238562', + 'Long':'-122.1141681' + }, + 'ShipAddr':{ + 'Id':'25', + 'Line1':'5647 Cypress Hill Ave.', + 'City':'Middlefield', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94303', + 'Lat':'37.4238562', + 'Long':'-122.1141681' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':362.07, + 'BalanceWithJobs':362.07, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'24', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T17:23:24-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Russ', + 'FamilyName':'Sonnenschein', + 'FullyQualifiedName':'Sonnenschein Family Store', + 'CompanyName':'Sonnenschein Family Store', + 'DisplayName':'Sonnenschein Family Store', + 'PrintOnCheckName':'Sonnenschein Family Store', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(650) 557-8463' + }, + 'PrimaryEmailAddr':{ + 'Address':'Familiystore@intuit.com' + } + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'26', + 'Line1':'898 Elm St.', + 'City':'Maplewood', + 'CountrySubDivisionCode':'NJ', + 'PostalCode':'07040', + 'Lat':'40.7312816', + 'Long':'-74.2652908' + }, + 'ShipAddr':{ + 'Id':'26', + 'Line1':'898 Elm St.', + 'City':'Maplewood', + 'CountrySubDivisionCode':'NJ', + 'PostalCode':'07040', + 'Lat':'40.7312816', + 'Long':'-74.2652908' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':160.0, + 'BalanceWithJobs':160.0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'25', + 'SyncToken':'3', + 'MetaData':{ + 'CreateTime':'2019-12-11T17:24:26-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Katsuyuki', + 'FamilyName':'Yanagawa', + 'FullyQualifiedName':'Sushi by Katsuyuki', + 'CompanyName':'Sushi by Katsuyuki', + 'DisplayName':'Sushi by Katsuyuki', + 'PrintOnCheckName':'Sushi by Katsuyuki', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(505) 570-0147' + }, + 'PrimaryEmailAddr':{ + 'Address':'Sushi@intuit.com' + } + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'27', + 'Line1':'78 First St.', + 'City':'Monlo Park', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94304', + 'Lat':'37.4585825', + 'Long':'-122.1352789' + }, + 'ShipAddr':{ + 'Id':'27', + 'Line1':'78 First St.', + 'City':'Monlo Park', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94304', + 'Lat':'37.4585825', + 'Long':'-122.1352789' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':414.72, + 'BalanceWithJobs':414.72, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'26', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T17:25:08-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Travis', + 'FamilyName':'Waldron', + 'FullyQualifiedName':'Travis Waldron', + 'DisplayName':'Travis Waldron', + 'PrintOnCheckName':'Travis Waldron', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(650) 557-9977' + }, + 'PrimaryEmailAddr':{ + 'Address':'Travis@Waldron.com' + } + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'28', + 'Line1':'202 Main St.', + 'City':'Tucson', + 'CountrySubDivisionCode':'AZ', + 'PostalCode':'85704', + 'Lat':'32.2242351', + 'Long':'-110.9758242' + }, + 'ShipAddr':{ + 'Id':'28', + 'Line1':'202 Main St.', + 'City':'Tucson', + 'CountrySubDivisionCode':'AZ', + 'PostalCode':'85704', + 'Lat':'32.2242351', + 'Long':'-110.9758242' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'27', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T17:26:07-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Dan', + 'FamilyName':'Wilks', + 'FullyQualifiedName':'Video Games by Dan', + 'CompanyName':'Video Games by Dan', + 'DisplayName':'Video Games by Dan', + 'PrintOnCheckName':'Video Games by Dan', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(650) 555-3456' + }, + 'PrimaryEmailAddr':{ + 'Address':'Videogames@intuit.com' + } + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'29', + 'Line1':'135 Broadway', + 'City':'Menlo Park', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94304', + 'Lat':'37.4846734', + 'Long':'-122.1989488' + }, + 'ShipAddr':{ + 'Id':'29', + 'Line1':'135 Broadway', + 'City':'Menlo Park', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94304', + 'Lat':'37.4846734', + 'Long':'-122.1989488' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'28', + 'SyncToken':'9', + 'MetaData':{ + 'CreateTime':'2019-12-11T17:28:21-08:00', + 'LastUpdatedTime':'2022-08-26T05:36:17-07:00' + }, + 'GivenName':'Whitney', + 'FamilyName':'Brewer', + 'FullyQualifiedName':'Wedding Planning by Whitney', + 'CompanyName':'Wedding Planning by Whitney', + 'DisplayName':'Wedding Planning by Whitney', + 'PrintOnCheckName':'Wedding Planning by Whitney', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(650) 557-2473' + }, + 'PrimaryEmailAddr':{ + 'Address':'Dream_Wedding@intuit.com' + }, + 'WebAddr':{ + 'URI':'http://www.dreamwedding.intuit.com' + } + }, + { + 'Taxable':False, + 'BillAddr':{ + 'Id':'30', + 'Line1':'45612 Main St.', + 'City':'Bayshore', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94326', + 'Lat':'45.256574', + 'Long':'-66.0943698' + }, + 'ShipAddr':{ + 'Id':'30', + 'Line1':'45612 Main St.', + 'City':'Bayshore', + 'CountrySubDivisionCode':'CA', + 'PostalCode':'94326', + 'Lat':'45.256574', + 'Long':'-66.0943698' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':375.0, + 'BalanceWithJobs':375.0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'29', + 'SyncToken':'1', + 'MetaData':{ + 'CreateTime':'2019-12-11T17:29:04-08:00', + 'LastUpdatedTime':'2021-08-05T23:53:08-07:00' + }, + 'GivenName':'Nicola', + 'FamilyName':'Weiskopf', + 'FullyQualifiedName':'Weiskopf Consulting', + 'CompanyName':'Weiskopf Consulting', + 'DisplayName':'Weiskopf Consulting', + 'PrintOnCheckName':'Weiskopf Consulting', + 'Active':True, + 'PrimaryPhone':{ + 'FreeFormNumber':'(650) 555-1423' + }, + 'PrimaryEmailAddr':{ + 'Address':'Consulting@intuit.com' + } + }, + { + 'Taxable':True, + 'BillAddr':{ + 'Id':'100' + }, + 'ShipAddr':{ + 'Id':'100' + }, + 'Job':False, + 'BillWithParent':False, + 'Balance':0, + 'BalanceWithJobs':0, + 'CurrencyRef':{ + 'value':'USD', + 'name':'United States Dollar' + }, + 'PreferredDeliveryMethod':'Print', + 'domain':'QBO', + 'sparse':False, + 'Id':'131', + 'SyncToken':'12', + 'MetaData':{ + 'CreateTime':'2022-07-26T04:23:18-07:00', + 'LastUpdatedTime':'2023-11-16T03:41:27-08:00' + }, + 'FullyQualifiedName':'wraith squad', + 'DisplayName':'wraith squad', + 'PrintOnCheckName':'wraith squad', + 'Active':True + } + ], + "create_new_auto_create_projects_expense_attributes_0": [ + { + 'count':123, + 'data':[ + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'236', + 'created_at':'2023-11-19T08:03:34.145903+00:00', + 'description':'Sage Intacct Project - Dylan, Id - 236', + 'display_name':'Dylan', + 'id':324523, + 'is_enabled':False, + 'name':'Dylan', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-19T08:11:33.531211+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'5000000000000341062', + 'created_at':'2023-11-19T07:44:57.223712+00:00', + 'description':'Sage Intacct Project - Nike Airforce, Id - 5000000000000341062', + 'display_name':'Nike Airforce', + 'id':324520, + 'is_enabled':False, + 'name':'Nike Airforce', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-19T07:45:38.187626+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'5000000000000341063', + 'created_at':'2023-11-19T07:44:57.224791+00:00', + 'description':'Sage Intacct Project - Yeezeys, Id - 5000000000000341063', + 'display_name':'Yeezeys', + 'id':324521, + 'is_enabled':False, + 'name':'Yeezeys', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-19T07:45:31.432503+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'5000000000000254926', + 'created_at':'2023-11-19T07:38:58.997216+00:00', + 'description':'Sage Intacct Project - Sravan, Id - 5000000000000254926', + 'display_name':'Sravan', + 'id':324519, + 'is_enabled':True, + 'name':'Sravan', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-19T07:38:58.997218+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'5000000000000240296', + 'created_at':'2023-11-19T07:38:58.996071+00:00', + 'description':'Sage Intacct Project - FAE:Mini FAE, Id - 5000000000000240296', + 'display_name':'FAE:Mini FAE', + 'id':324518, + 'is_enabled':True, + 'name':'FAE:Mini FAE', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-19T07:38:58.996073+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'5000000000000142510', + 'created_at':'2023-11-19T07:38:58.995045+00:00', + 'description':'Sage Intacct Project - FAE, Id - 5000000000000142510', + 'display_name':'FAE', + 'id':324517, + 'is_enabled':True, + 'name':'FAE', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-19T07:38:58.995047+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'5000000000000219489', + 'created_at':'2023-11-19T07:38:58.994024+00:00', + 'description':'Sage Intacct Project - Fabrication, Id - 5000000000000219489', + 'display_name':'Fabrication', + 'id':324516, + 'is_enabled':True, + 'name':'Fabrication', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-19T07:38:58.994026+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'5000000000000307078', + 'created_at':'2023-11-19T07:38:58.993029+00:00', + 'description':'Sage Intacct Project - Ashwin Class, Id - 5000000000000307078', + 'display_name':'Ashwin Class', + 'id':324515, + 'is_enabled':True, + 'name':'Ashwin Class', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-19T07:38:58.993031+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'5000000000000142509', + 'created_at':'2023-11-19T07:38:58.991912+00:00', + 'description':'Sage Intacct Project - Adidas, Id - 5000000000000142509', + 'display_name':'Adidas', + 'id':324514, + 'is_enabled':True, + 'name':'Adidas', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-19T07:38:58.991916+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'190', + 'created_at':'2023-11-14T17:24:29.527176+00:00', + 'description':'Sage Intacct Project - 12 - Project 1, Id - 190', + 'display_name':'12 - Project 1', + 'id':324444, + 'is_enabled':False, + 'name':'12 - Project 1', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-16T12:44:37.005075+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'7', + 'created_at':'2023-11-16T12:29:43.809341+00:00', + 'description':'Sage Intacct Project - samundar, Id - 7', + 'display_name':'samundar', + 'id':324507, + 'is_enabled':True, + 'name':'samundar', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-16T12:29:43.809344+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'3', + 'created_at':'2023-11-16T12:25:28.978676+00:00', + 'description':'Sage Intacct Project - suhas_p1, Id - 3', + 'display_name':'suhas_p1', + 'id':324506, + 'is_enabled':True, + 'name':'suhas_p1', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-16T12:25:28.978678+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'6', + 'created_at':'2023-11-16T12:25:28.978054+00:00', + 'description':'Sage Intacct Project - Delhi, Id - 6', + 'display_name':'Delhi', + 'id':324505, + 'is_enabled':True, + 'name':'Delhi', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-16T12:25:28.978056+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'5', + 'created_at':'2023-11-16T12:25:28.977406+00:00', + 'description':'Sage Intacct Project - Chennai, Id - 5', + 'display_name':'Chennai', + 'id':324504, + 'is_enabled':True, + 'name':'Chennai', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-16T12:25:28.977408+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'2', + 'created_at':'2023-11-16T12:25:28.976743+00:00', + 'description':'Sage Intacct Project - Bebe Rexha, Id - 2', + 'display_name':'Bebe Rexha', + 'id':324503, + 'is_enabled':True, + 'name':'Bebe Rexha', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-16T12:25:28.976745+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'1', + 'created_at':'2023-11-16T12:25:28.976111+00:00', + 'description':'Sage Intacct Project - Bangalore, Id - 1', + 'display_name':'Bangalore', + 'id':324502, + 'is_enabled':True, + 'name':'Bangalore', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-16T12:25:28.976113+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'4', + 'created_at':'2023-11-16T12:25:28.975341+00:00', + 'description':'Sage Intacct Project - Accountants Inc, Id - 4', + 'display_name':'Accountants Inc', + 'id':324501, + 'is_enabled':True, + 'name':'Accountants Inc', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-16T12:25:28.975344+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'189', + 'created_at':'2023-11-14T17:24:29.533269+00:00', + 'description':'Sage Intacct Project - Ashu Staging, Id - 189', + 'display_name':'Ashu Staging', + 'id':324447, + 'is_enabled':False, + 'name':'Ashu Staging', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-16T11:52:30.913836+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'233', + 'created_at':'2023-11-16T11:40:19.350887+00:00', + 'description':'Sage Intacct Project - laysBlue, Id - 233', + 'display_name':'laysBlue', + 'id':324498, + 'is_enabled':False, + 'name':'laysBlue', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-16T11:41:54.329252+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'234', + 'created_at':'2023-11-16T11:40:19.354916+00:00', + 'description':'Sage Intacct Project - laysRed, Id - 234', + 'display_name':'laysRed', + 'id':324499, + 'is_enabled':True, + 'name':'laysRed', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-16T11:40:19.354920+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'29', + 'created_at':'2023-11-14T17:24:29.576510+00:00', + 'description':'Sage Intacct Project - Weiskopf Consulting, Id - 29', + 'display_name':'Weiskopf Consulting', + 'id':324478, + 'is_enabled':True, + 'name':'Weiskopf Consulting', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-14T17:24:29.576511+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'28', + 'created_at':'2023-11-14T17:24:29.575519+00:00', + 'description':'Sage Intacct Project - Wedding Planning by Whitney, Id - 28', + 'display_name':'Wedding Planning by Whitney', + 'id':324477, + 'is_enabled':True, + 'name':'Wedding Planning by Whitney', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-14T17:24:29.575521+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'27', + 'created_at':'2023-11-14T17:24:29.574518+00:00', + 'description':'Sage Intacct Project - Video Games by Dan, Id - 27', + 'display_name':'Video Games by Dan', + 'id':324476, + 'is_enabled':True, + 'name':'Video Games by Dan', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-14T17:24:29.574520+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'26', + 'created_at':'2023-11-14T17:24:29.573404+00:00', + 'description':'Sage Intacct Project - Travis Waldron, Id - 26', + 'display_name':'Travis Waldron', + 'id':324475, + 'is_enabled':True, + 'name':'Travis Waldron', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-14T17:24:29.573407+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'25', + 'created_at':'2023-11-14T17:24:29.572079+00:00', + 'description':'Sage Intacct Project - Sushi by Katsuyuki, Id - 25', + 'display_name':'Sushi by Katsuyuki', + 'id':324474, + 'is_enabled':True, + 'name':'Sushi by Katsuyuki', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-14T17:24:29.572081+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'24', + 'created_at':'2023-11-14T17:24:29.570989+00:00', + 'description':'Sage Intacct Project - Sonnenschein Family Store, Id - 24', + 'display_name':'Sonnenschein Family Store', + 'id':324473, + 'is_enabled':True, + 'name':'Sonnenschein Family Store', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-14T17:24:29.570991+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'23', + 'created_at':'2023-11-14T17:24:29.569734+00:00', + 'description':'Sage Intacct Project - Shara Barnett:Barnett Design, Id - 23', + 'display_name':'Shara Barnett:Barnett Design', + 'id':324472, + 'is_enabled':True, + 'name':'Shara Barnett:Barnett Design', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-14T17:24:29.569736+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'22', + 'created_at':'2023-11-14T17:24:29.568540+00:00', + 'description':'Sage Intacct Project - Shara Barnett, Id - 22', + 'display_name':'Shara Barnett', + 'id':324471, + 'is_enabled':True, + 'name':'Shara Barnett', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-14T17:24:29.568542+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'21', + 'created_at':'2023-11-14T17:24:29.567471+00:00', + 'description':'Sage Intacct Project - Rondonuwu Fruit and Vegi, Id - 21', + 'display_name':'Rondonuwu Fruit and Vegi', + 'id':324470, + 'is_enabled':True, + 'name':'Rondonuwu Fruit and Vegi', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-14T17:24:29.567473+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'20', + 'created_at':'2023-11-14T17:24:29.566397+00:00', + 'description':'Sage Intacct Project - Red Rock Diner, Id - 20', + 'display_name':'Red Rock Diner', + 'id':324469, + 'is_enabled':True, + 'name':'Red Rock Diner', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-14T17:24:29.566398+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'19', + 'created_at':'2023-11-14T17:24:29.565369+00:00', + 'description':'Sage Intacct Project - Rago Travel Agency, Id - 19', + 'display_name':'Rago Travel Agency', + 'id':324468, + 'is_enabled':True, + 'name':'Rago Travel Agency', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-14T17:24:29.565371+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'15', + 'created_at':'2023-11-14T17:24:29.564366+00:00', + 'description':"Sage Intacct Project - Pye's Cakes, Id - 15", + 'display_name':"Pye's Cakes", + 'id':324467, + 'is_enabled':True, + 'name':"Pye's Cakes", + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-14T17:24:29.564368+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'135', + 'created_at':'2023-11-14T17:24:29.563287+00:00', + 'description':'Sage Intacct Project - New Inactive boi, Id - 135', + 'display_name':'New Inactive boi', + 'id':324466, + 'is_enabled':True, + 'name':'New Inactive boi', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-14T17:24:29.563289+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'133', + 'created_at':'2023-11-14T17:24:29.562203+00:00', + 'description':'Sage Intacct Project - naruto uzumaki, Id - 133', + 'display_name':'naruto uzumaki', + 'id':324465, + 'is_enabled':True, + 'name':'naruto uzumaki', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-14T17:24:29.562205+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'17', + 'created_at':'2023-11-14T17:24:29.561127+00:00', + 'description':'Sage Intacct Project - Mark Cho, Id - 17', + 'display_name':'Mark Cho', + 'id':324464, + 'is_enabled':True, + 'name':'Mark Cho', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-14T17:24:29.561129+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'14', + 'created_at':'2023-11-14T17:24:29.560069+00:00', + 'description':'Sage Intacct Project - Kate Whelan, Id - 14', + 'display_name':'Kate Whelan', + 'id':324463, + 'is_enabled':True, + 'name':'Kate Whelan', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-14T17:24:29.560071+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'13', + 'created_at':'2023-11-14T17:24:29.558827+00:00', + 'description':'Sage Intacct Project - John Melton, Id - 13', + 'display_name':'John Melton', + 'id':324462, + 'is_enabled':True, + 'name':'John Melton', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-14T17:24:29.558829+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'12', + 'created_at':'2023-11-14T17:24:29.557701+00:00', + 'description':"Sage Intacct Project - Jeff's Jalopies, Id - 12", + 'display_name':"Jeff's Jalopies", + 'id':324461, + 'is_enabled':True, + 'name':"Jeff's Jalopies", + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-14T17:24:29.557703+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'11', + 'created_at':'2023-11-14T17:24:29.556621+00:00', + 'description':'Sage Intacct Project - Gevelber Photography, Id - 11', + 'display_name':'Gevelber Photography', + 'id':324460, + 'is_enabled':True, + 'name':'Gevelber Photography', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-14T17:24:29.556623+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'10', + 'created_at':'2023-11-14T17:24:29.555593+00:00', + 'description':'Sage Intacct Project - Geeta Kalapatapu, Id - 10', + 'display_name':'Geeta Kalapatapu', + 'id':324459, + 'is_enabled':True, + 'name':'Geeta Kalapatapu', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-14T17:24:29.555595+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'9', + 'created_at':'2023-11-14T17:24:29.554568+00:00', + 'description':'Sage Intacct Project - Freeman Sporting Goods:55 Twin Lane, Id - 9', + 'display_name':'Freeman Sporting Goods:55 Twin Lane', + 'id':324458, + 'is_enabled':True, + 'name':'Freeman Sporting Goods:55 Twin Lane', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-14T17:24:29.554570+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'8', + 'created_at':'2023-11-14T17:24:29.553466+00:00', + 'description':'Sage Intacct Project - Freeman Sporting Goods:0969 Ocean View Road, Id - 8', + 'display_name':'Freeman Sporting Goods:0969 Ocean View Road', + 'id':324457, + 'is_enabled':True, + 'name':'Freeman Sporting Goods:0969 Ocean View Road', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-14T17:24:29.553468+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'7', + 'created_at':'2023-11-14T17:24:29.552437+00:00', + 'description':'Sage Intacct Project - Freeman Sporting Goods, Id - 7', + 'display_name':'Freeman Sporting Goods', + 'id':324456, + 'is_enabled':True, + 'name':'Freeman Sporting Goods', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-14T17:24:29.552439+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'6', + 'created_at':'2023-11-14T17:24:29.550282+00:00', + 'description':'Sage Intacct Project - Dylan Sollfrank, Id - 6', + 'display_name':'Dylan Sollfrank', + 'id':324455, + 'is_enabled':True, + 'name':'Dylan Sollfrank', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-14T17:24:29.550284+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'5', + 'created_at':'2023-11-14T17:24:29.549104+00:00', + 'description':'Sage Intacct Project - Dukes Basketball Camp, Id - 5', + 'display_name':'Dukes Basketball Camp', + 'id':324454, + 'is_enabled':True, + 'name':'Dukes Basketball Camp', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-14T17:24:29.549108+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'59', + 'created_at':'2023-11-14T17:24:29.546512+00:00', + 'description':'Sage Intacct Project - Diego Rodriguez:Test Project, Id - 59', + 'display_name':'Diego Rodriguez:Test Project', + 'id':324453, + 'is_enabled':True, + 'name':'Diego Rodriguez:Test Project', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-14T17:24:29.546516+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'4', + 'created_at':'2023-11-14T17:24:29.544203+00:00', + 'description':'Sage Intacct Project - Diego Rodriguez, Id - 4', + 'display_name':'Diego Rodriguez', + 'id':324452, + 'is_enabled':True, + 'name':'Diego Rodriguez', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-14T17:24:29.544208+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'136', + 'created_at':'2023-11-14T17:24:29.540976+00:00', + 'description':'Sage Intacct Project - Cred Technologies, Id - 136', + 'display_name':'Cred Technologies', + 'id':324451, + 'is_enabled':True, + 'name':'Cred Technologies', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-14T17:24:29.540980+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'3', + 'created_at':'2023-11-14T17:24:29.538002+00:00', + 'description':'Sage Intacct Project - Cool Cars, Id - 3', + 'display_name':'Cool Cars', + 'id':324450, + 'is_enabled':True, + 'name':'Cool Cars', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-14T17:24:29.538004+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'2', + 'created_at':'2023-11-14T17:24:29.536760+00:00', + 'description':"Sage Intacct Project - Bill's Windsurf Shop, Id - 2", + 'display_name':"Bill's Windsurf Shop", + 'id':324449, + 'is_enabled':True, + 'name':"Bill's Windsurf Shop", + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-14T17:24:29.536763+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'103', + 'created_at':'2023-11-14T17:24:29.535399+00:00', + 'description':'Sage Intacct Project - Ashwinn, Id - 103', + 'display_name':'Ashwinn', + 'id':324448, + 'is_enabled':True, + 'name':'Ashwinn', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-14T17:24:29.535402+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'58', + 'created_at':'2023-11-14T17:24:29.529869+00:00', + 'description':"Sage Intacct Project - Amy's Bird Sanctuary:Test Project, Id - 58", + 'display_name':"Amy's Bird Sanctuary:Test Project", + 'id':324446, + 'is_enabled':True, + 'name':"Amy's Bird Sanctuary:Test Project", + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-14T17:24:29.529871+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'1', + 'created_at':'2023-11-14T17:24:29.528460+00:00', + 'description':"Sage Intacct Project - Amy's Bird Sanctuary, Id - 1", + 'display_name':"Amy's Bird Sanctuary", + 'id':324445, + 'is_enabled':True, + 'name':"Amy's Bird Sanctuary", + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-14T17:24:29.528462+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'188', + 'created_at':'2023-11-14T17:24:29.525614+00:00', + 'description':'Sage Intacct Project - 1047 S Ocean Blvd, Id - 188', + 'display_name':'1047 S Ocean Blvd', + 'id':324443, + 'is_enabled':True, + 'name':'1047 S Ocean Blvd', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-14T17:24:29.525618+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'10061', + 'created_at':'2023-10-31T13:47:59.304999+00:00', + 'description':'Sage Intacct Project - Branding Analysis, Id - 10061', + 'display_name':'Branding Analysis', + 'id':324390, + 'is_enabled':True, + 'name':'Branding Analysis', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:59.304999+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'10063', + 'created_at':'2023-10-31T13:47:59.304999+00:00', + 'description':'Sage Intacct Project - Branding Follow Up, Id - 10063', + 'display_name':'Branding Follow Up', + 'id':324391, + 'is_enabled':True, + 'name':'Branding Follow Up', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:59.304999+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'10064', + 'created_at':'2023-10-31T13:47:59.304999+00:00', + 'description':'Sage Intacct Project - Direct Mail Campaign, Id - 10064', + 'display_name':'Direct Mail Campaign', + 'id':324392, + 'is_enabled':True, + 'name':'Direct Mail Campaign', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:59.304999+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'10062', + 'created_at':'2023-10-31T13:47:59.304999+00:00', + 'description':'Sage Intacct Project - Ecommerce Campaign, Id - 10062', + 'display_name':'Ecommerce Campaign', + 'id':324393, + 'is_enabled':True, + 'name':'Ecommerce Campaign', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:59.304999+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'10088', + 'created_at':'2023-09-14T11:19:35.533886+00:00', + 'description':'Sage Intacct Project - Yujiro, Id - 10088', + 'display_name':'Yujiro', + 'id':323782, + 'is_enabled':True, + 'name':'Yujiro', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.662319+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'10085', + 'created_at':'2023-09-14T11:19:35.533886+00:00', + 'description':'Sage Intacct Project - Youtube proj, Id - 10085', + 'display_name':'Youtube proj', + 'id':323781, + 'is_enabled':True, + 'name':'Youtube proj', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.660995+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'10092', + 'created_at':'2023-09-14T11:19:35.533886+00:00', + 'description':'Sage Intacct Project - X bow, Id - 10092', + 'display_name':'X bow', + 'id':323780, + 'is_enabled':True, + 'name':'X bow', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.660167+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'10094', + 'created_at':'2023-09-14T11:19:35.533886+00:00', + 'description':'Sage Intacct Project - todoroki, Id - 10094', + 'display_name':'todoroki', + 'id':323779, + 'is_enabled':True, + 'name':'todoroki', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.655693+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'Template-TM', + 'created_at':'2023-09-14T11:19:35.533886+00:00', + 'description':'Sage Intacct Project - T&M Project with Five Tasks, Id - Template-TM', + 'display_name':'T&M Project with Five Tasks', + 'id':323778, + 'is_enabled':True, + 'name':'T&M Project with Five Tasks', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.654221+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'10082', + 'created_at':'2023-09-14T11:19:35.533886+00:00', + 'description':'Sage Intacct Project - Support Taxes, Id - 10082', + 'display_name':'Support Taxes', + 'id':323777, + 'is_enabled':True, + 'name':'Support Taxes', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.653208+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'10090', + 'created_at':'2023-09-14T11:19:35.533886+00:00', + 'description':'Sage Intacct Project - Retsu kaio, Id - 10090', + 'display_name':'Retsu kaio', + 'id':323776, + 'is_enabled':True, + 'name':'Retsu kaio', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.652053+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'10081', + 'created_at':'2023-09-14T11:19:35.533886+00:00', + 'description':'Sage Intacct Project - Platform APIs, Id - 10081', + 'display_name':'Platform APIs', + 'id':323775, + 'is_enabled':True, + 'name':'Platform APIs', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.651426+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'10097', + 'created_at':'2023-09-14T11:19:35.533886+00:00', + 'description':'Sage Intacct Project - Nilesh Changes Labhvam Changes Again, Id - 10097', + 'display_name':'Nilesh Changes Labhvam Changes Again', + 'id':323774, + 'is_enabled':True, + 'name':'Nilesh Changes Labhvam Changes Again', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.650905+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'10080', + 'created_at':'2023-09-14T11:19:35.533886+00:00', + 'description':'Sage Intacct Project - Mobile App Redesign, Id - 10080', + 'display_name':'Mobile App Redesign', + 'id':323773, + 'is_enabled':True, + 'name':'Mobile App Redesign', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.650327+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'10104', + 'created_at':'2023-09-14T11:19:35.533886+00:00', + 'description':'Sage Intacct Project - mega knight 2, Id - 10104', + 'display_name':'mega knight 2', + 'id':323772, + 'is_enabled':True, + 'name':'mega knight 2', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.650160+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'10103', + 'created_at':'2023-09-14T11:19:35.533886+00:00', + 'description':'Sage Intacct Project - mega knight, Id - 10103', + 'display_name':'mega knight', + 'id':323771, + 'is_enabled':True, + 'name':'mega knight', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.649522+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'10091', + 'created_at':'2023-09-14T11:19:35.533886+00:00', + 'description':'Sage Intacct Project - Magic archer, Id - 10091', + 'display_name':'Magic archer', + 'id':323770, + 'is_enabled':True, + 'name':'Magic archer', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.649004+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'10099', + 'created_at':'2023-09-14T11:19:35.533886+00:00', + 'description':'Sage Intacct Project - kakashi prod, Id - 10099', + 'display_name':'kakashi prod', + 'id':323769, + 'is_enabled':True, + 'name':'kakashi prod', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.648430+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'10098', + 'created_at':'2023-09-14T11:19:35.533886+00:00', + 'description':'Sage Intacct Project - Itachi prod, Id - 10098', + 'display_name':'Itachi prod', + 'id':323768, + 'is_enabled':True, + 'name':'Itachi prod', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.647900+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'10076', + 'created_at':'2023-09-14T11:19:35.533886+00:00', + 'description':'Sage Intacct Project - Integrations, Id - 10076', + 'display_name':'Integrations', + 'id':323767, + 'is_enabled':True, + 'name':'Integrations', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.647284+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'10101', + 'created_at':'2023-09-14T11:19:35.533886+00:00', + 'description':'Sage Intacct Project - Hard, Id - 10101', + 'display_name':'Hard', + 'id':323766, + 'is_enabled':True, + 'name':'Hard', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.646555+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'10025', + 'created_at':'2023-09-14T11:19:35.533886+00:00', + 'description':'Sage Intacct Project - General Overhead-Current, Id - 10025', + 'display_name':'General Overhead-Current', + 'id':323765, + 'is_enabled':True, + 'name':'General Overhead-Current', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.646026+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'10000', + 'created_at':'2023-09-14T11:19:35.533886+00:00', + 'description':'Sage Intacct Project - General Overhead, Id - 10000', + 'display_name':'General Overhead', + 'id':323764, + 'is_enabled':True, + 'name':'General Overhead', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.644897+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'10077', + 'created_at':'2023-09-14T11:19:35.533886+00:00', + 'description':'Sage Intacct Project - Fyle Sage Intacct Integration, Id - 10077', + 'display_name':'Fyle Sage Intacct Integration', + 'id':323763, + 'is_enabled':True, + 'name':'Fyle Sage Intacct Integration', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.644271+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'10078', + 'created_at':'2023-09-14T11:19:35.533886+00:00', + 'description':'Sage Intacct Project - Fyle NetSuite Integration, Id - 10078', + 'display_name':'Fyle NetSuite Integration', + 'id':323762, + 'is_enabled':True, + 'name':'Fyle NetSuite Integration', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.643628+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'Template-FF', + 'created_at':'2023-09-14T11:19:35.533886+00:00', + 'description':'Sage Intacct Project - Fixed Fee Project with Five Tasks, Id - Template-FF', + 'display_name':'Fixed Fee Project with Five Tasks', + 'id':323761, + 'is_enabled':True, + 'name':'Fixed Fee Project with Five Tasks', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.642935+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'10089', + 'created_at':'2023-09-14T11:19:35.533886+00:00', + 'description':'Sage Intacct Project - Electro wizard, Id - 10089', + 'display_name':'Electro wizard', + 'id':323760, + 'is_enabled':True, + 'name':'Electro wizard', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.642139+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'10095', + 'created_at':'2023-09-14T11:19:35.533886+00:00', + 'description':'Sage Intacct Project - Deku, Id - 10095', + 'display_name':'Deku', + 'id':323759, + 'is_enabled':True, + 'name':'Deku', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.640971+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'10093', + 'created_at':'2023-09-14T11:19:35.533886+00:00', + 'description':'Sage Intacct Project - bakugo, Id - 10093', + 'display_name':'bakugo', + 'id':323758, + 'is_enabled':True, + 'name':'bakugo', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.639789+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'67', + 'created_at':'2023-05-04T06:59:31.151906+00:00', + 'description':'Project - Adwin Ko:Leaf project, Id - 67', + 'display_name':'Adwin Ko:Leaf project', + 'id':320072, + 'is_enabled':True, + 'name':'Adwin Ko:Leaf project', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.638744+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'5', + 'created_at':'2023-04-24T17:45:57.913533+00:00', + 'description':'Project - Whitehead and Sons, Id - 5', + 'display_name':'Whitehead and Sons', + 'id':320035, + 'is_enabled':True, + 'name':'Whitehead and Sons', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.636837+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'22', + 'created_at':'2023-04-24T17:45:57.913533+00:00', + 'description':'Project - Rob deMontarnal, Id - 22', + 'display_name':'Rob deMontarnal', + 'id':320034, + 'is_enabled':True, + 'name':'Rob deMontarnal', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.635957+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'66', + 'created_at':'2023-04-24T17:45:57.913533+00:00', + 'description':'Project - Oxon Insurance Agency:Oxon - Retreat, Id - 66', + 'display_name':'Oxon Insurance Agency:Oxon - Retreat', + 'id':320033, + 'is_enabled':True, + 'name':'Oxon Insurance Agency:Oxon - Retreat', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.634041+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'65', + 'created_at':'2023-04-24T17:45:57.913533+00:00', + 'description':'Project - Oxon Insurance Agency:Oxon - Holiday Party, Id - 65', + 'display_name':'Oxon Insurance Agency:Oxon - Holiday Party', + 'id':320032, + 'is_enabled':True, + 'name':'Oxon Insurance Agency:Oxon - Holiday Party', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.633278+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'2', + 'created_at':'2023-04-24T17:45:57.913533+00:00', + 'description':'Project - Oxon Insurance Agency, Id - 2', + 'display_name':'Oxon Insurance Agency', + 'id':320031, + 'is_enabled':True, + 'name':'Oxon Insurance Agency', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.632631+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'21', + 'created_at':'2023-04-24T17:45:57.913533+00:00', + 'description':'Project - Nadia Phillipchuk, Id - 21', + 'display_name':'Nadia Phillipchuk', + 'id':320030, + 'is_enabled':True, + 'name':'Nadia Phillipchuk', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.631908+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'20', + 'created_at':'2023-04-24T17:45:57.913533+00:00', + 'description':'Project - Moturu Tapasvi, Id - 20', + 'display_name':'Moturu Tapasvi', + 'id':320029, + 'is_enabled':True, + 'name':'Moturu Tapasvi', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.630384+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'10', + 'created_at':'2023-04-24T17:45:57.913533+00:00', + 'description':'Project - Lew Plumbing, Id - 10', + 'display_name':'Lew Plumbing', + 'id':320028, + 'is_enabled':True, + 'name':'Lew Plumbing', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.628692+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'19', + 'created_at':'2023-04-24T17:45:57.913533+00:00', + 'description':'Project - Karna Nisewaner, Id - 19', + 'display_name':'Karna Nisewaner', + 'id':320027, + 'is_enabled':True, + 'name':'Karna Nisewaner', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.628068+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'18', + 'created_at':'2023-04-24T17:45:57.913533+00:00', + 'description':'Project - Kari Steblay, Id - 18', + 'display_name':'Kari Steblay', + 'id':320026, + 'is_enabled':True, + 'name':'Kari Steblay', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.627301+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'17', + 'created_at':'2023-04-24T17:45:57.913533+00:00', + 'description':'Project - Justine Outland, Id - 17', + 'display_name':'Justine Outland', + 'id':320025, + 'is_enabled':True, + 'name':'Justine Outland', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.626467+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'16', + 'created_at':'2023-04-24T17:45:57.913533+00:00', + 'description':'Project - Jordan Burgess, Id - 16', + 'display_name':'Jordan Burgess', + 'id':320024, + 'is_enabled':True, + 'name':'Jordan Burgess', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.623631+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'15', + 'created_at':'2023-04-24T17:45:57.913533+00:00', + 'description':'Project - Jen Zaccarella, Id - 15', + 'display_name':'Jen Zaccarella', + 'id':320023, + 'is_enabled':True, + 'name':'Jen Zaccarella', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.622893+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'14', + 'created_at':'2023-04-24T17:45:57.913533+00:00', + 'description':'Project - Jacint Tumacder, Id - 14', + 'display_name':'Jacint Tumacder', + 'id':320022, + 'is_enabled':True, + 'name':'Jacint Tumacder', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.621632+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'11', + 'created_at':'2023-04-24T17:45:57.913533+00:00', + 'description':'Project - Ho Engineering Company, Id - 11', + 'display_name':'Ho Engineering Company', + 'id':320021, + 'is_enabled':True, + 'name':'Ho Engineering Company', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.620103+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'13', + 'created_at':'2023-04-24T17:45:57.913533+00:00', + 'description':'Project - Himateja Madala, Id - 13', + 'display_name':'Himateja Madala', + 'id':320020, + 'is_enabled':True, + 'name':'Himateja Madala', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.618687+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'12', + 'created_at':'2023-04-24T17:45:57.913533+00:00', + 'description':'Project - Hazel Robinson, Id - 12', + 'display_name':'Hazel Robinson', + 'id':320019, + 'is_enabled':True, + 'name':'Hazel Robinson', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.617130+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'9', + 'created_at':'2023-04-24T17:45:57.913533+00:00', + 'description':'Project - Froilan Rosqueta, Id - 9', + 'display_name':'Froilan Rosqueta', + 'id':320018, + 'is_enabled':True, + 'name':'Froilan Rosqueta', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.615904+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'8', + 'created_at':'2023-04-24T17:45:57.913533+00:00', + 'description':'Project - Ecker Designs, Id - 8', + 'display_name':'Ecker Designs', + 'id':320017, + 'is_enabled':True, + 'name':'Ecker Designs', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.614926+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'7', + 'created_at':'2023-04-24T17:45:57.913533+00:00', + 'description':"Project - Clement's Cleaners, Id - 7", + 'display_name':"Clement's Cleaners", + 'id':320016, + 'is_enabled':True, + 'name':"Clement's Cleaners", + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.614232+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'6', + 'created_at':'2023-04-24T17:45:57.913533+00:00', + 'description':'Project - Cheng-Cheng Lok, Id - 6', + 'display_name':'Cheng-Cheng Lok', + 'id':320015, + 'is_enabled':True, + 'name':'Cheng-Cheng Lok', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.613555+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'64', + 'created_at':'2023-04-24T17:45:57.913533+00:00', + 'description':"Project - Chadha's Consultants, Id - 64", + 'display_name':"Chadha's Consultants", + 'id':320014, + 'is_enabled':True, + 'name':"Chadha's Consultants", + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.612912+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'4', + 'created_at':'2023-04-24T17:45:57.913533+00:00', + 'description':"Project - Cathy's Consulting Company, Id - 4", + 'display_name':"Cathy's Consulting Company", + 'id':320013, + 'is_enabled':True, + 'name':"Cathy's Consulting Company", + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.611688+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'3', + 'created_at':'2023-04-24T17:45:57.913533+00:00', + 'description':'Project - Benjamin Yeung, Id - 3', + 'display_name':'Benjamin Yeung', + 'id':320012, + 'is_enabled':True, + 'name':'Benjamin Yeung', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.610357+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'60', + 'created_at':'2023-04-24T17:45:57.913533+00:00', + 'description':'Project - Anilkumar Pillai, Id - 60', + 'display_name':'Anilkumar Pillai', + 'id':320011, + 'is_enabled':True, + 'name':'Anilkumar Pillai', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.609650+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'59', + 'created_at':'2023-04-24T17:45:57.913533+00:00', + 'description':'Project - Andre Prefontaine, Id - 59', + 'display_name':'Andre Prefontaine', + 'id':320010, + 'is_enabled':True, + 'name':'Andre Prefontaine', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.608759+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'58', + 'created_at':'2023-04-24T17:45:57.913533+00:00', + 'description':'Project - Alex Blakey, Id - 58', + 'display_name':'Alex Blakey', + 'id':320009, + 'is_enabled':True, + 'name':'Alex Blakey', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.607587+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'1', + 'created_at':'2023-04-24T17:45:57.913533+00:00', + 'description':'Project - Adwin Ko, Id - 1', + 'display_name':'Adwin Ko', + 'id':320008, + 'is_enabled':True, + 'name':'Adwin Ko', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.606263+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'61', + 'created_at':'2023-04-24T17:45:57.913533+00:00', + 'description':'Project - Abercrombie International Group, Id - 61', + 'display_name':'Abercrombie International Group', + 'id':320007, + 'is_enabled':True, + 'name':'Abercrombie International Group', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.605052+00:00' + }, + { + 'approver_user_ids':[ + 'usgybGjChCDu', + None + ], + 'approver_users':[{ + 'email':'approver1@fyleforcad.creatine', + 'full_name':'Ryan Gallagher', + 'id':'usgybGjChCDu' + } + ], + 'category_ids':[ + 274748, + 274749, + 274750, + 274751 + ], + 'code':'07416WSPY6', + 'created_at':'2023-04-06T06:13:57.751976+00:00', + 'description':'9707W0RXRH', + 'display_name':'Project 10', + 'id':319781, + 'is_enabled':True, + 'name':'Project 10', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.603679+00:00' + }, + { + 'approver_user_ids':[ + 'usgybGjChCDu', + None + ], + 'approver_users':[{ + 'email':'approver1@fyleforcad.creatine', + 'full_name':'Ryan Gallagher', + 'id':'usgybGjChCDu' + } + ], + 'category_ids':[ + 270943, + 270944, + 270945, + 270946, + 270947, + 274746, + 274747, + 274748, + 274749, + 274750, + 274751 + ], + 'code':'U49A1O68IW', + 'created_at':'2023-04-06T06:13:56.927814+00:00', + 'description':'Y12W0D19I1', + 'display_name':'Project 9', + 'id':319780, + 'is_enabled':True, + 'name':'Project 9', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.602737+00:00' + }, + { + 'approver_user_ids':[ + 'usgybGjChCDu', + None + ], + 'approver_users':[{ + 'email':'approver1@fyleforcad.creatine', + 'full_name':'Ryan Gallagher', + 'id':'usgybGjChCDu' + } + ], + 'category_ids':[ + 274749, + 274750, + 274751 + ], + 'code':'L830V6UAC2', + 'created_at':'2023-04-06T06:13:56.102547+00:00', + 'description':'H06PU3PJ4F', + 'display_name':'Project 8', + 'id':319779, + 'is_enabled':True, + 'name':'Project 8', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.601514+00:00' + }, + { + 'approver_user_ids':[ + 'usgybGjChCDu', + None + ], + 'approver_users':[{ + 'email':'approver1@fyleforcad.creatine', + 'full_name':'Ryan Gallagher', + 'id':'usgybGjChCDu' + } + ], + 'category_ids':[ + 270938, + 270939, + 270940, + 270941, + 270942, + 270943, + 270944, + 270945, + 270946, + 270947, + 274746, + 274747, + 274748, + 274749, + 274750, + 274751 + ], + 'code':'FSQM7CGOHP', + 'created_at':'2023-04-06T06:13:55.196416+00:00', + 'description':'B6ZMYQHGFK', + 'display_name':'Project 7', + 'id':319778, + 'is_enabled':True, + 'name':'Project 7', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.600128+00:00' + }, + { + 'approver_user_ids':[ + 'usgybGjChCDu', + None + ], + 'approver_users':[{ + 'email':'approver1@fyleforcad.creatine', + 'full_name':'Ryan Gallagher', + 'id':'usgybGjChCDu' + } + ], + 'category_ids':[ + 274749, + 274750, + 274751 + ], + 'code':'2YPERHEKVH', + 'created_at':'2023-04-06T06:13:54.365893+00:00', + 'description':'DHO4MRP7TS', + 'display_name':'Project 6', + 'id':319777, + 'is_enabled':True, + 'name':'Project 6', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.599087+00:00' + }, + { + 'approver_user_ids':[ + 'usgybGjChCDu', + None + ], + 'approver_users':[{ + 'email':'approver1@fyleforcad.creatine', + 'full_name':'Ryan Gallagher', + 'id':'usgybGjChCDu' + } + ], + 'category_ids':[ + 270947, + 274746, + 274747, + 274748, + 274749, + 274750, + 274751 + ], + 'code':'BX3QN6JSRT', + 'created_at':'2023-04-06T06:13:53.564131+00:00', + 'description':'U62XWYR7E4', + 'display_name':'Project 5', + 'id':319776, + 'is_enabled':True, + 'name':'Project 5', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.597362+00:00' + }, + { + 'approver_user_ids':[ + 'usgybGjChCDu', + None + ], + 'approver_users':[{ + 'email':'approver1@fyleforcad.creatine', + 'full_name':'Ryan Gallagher', + 'id':'usgybGjChCDu' + } + ], + 'category_ids':[ + 274746, + 274747, + 274748, + 274749, + 274750, + 274751 + ], + 'code':'DAA1JGIFJ7', + 'created_at':'2023-04-06T06:13:52.761308+00:00', + 'description':'1KS8A3TIN0', + 'display_name':'Project 4', + 'id':319775, + 'is_enabled':True, + 'name':'Project 4', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.595855+00:00' + }, + { + 'approver_user_ids':[ + 'usgybGjChCDu', + None + ], + 'approver_users':[{ + 'email':'approver1@fyleforcad.creatine', + 'full_name':'Ryan Gallagher', + 'id':'usgybGjChCDu' + } + ], + 'category_ids':[ + 253385, + 253386, + 253390, + 253394, + 253395, + 253396, + 253397, + ], + 'code':'8JF4QB0IK3', + 'created_at':'2023-04-06T06:13:51.957540+00:00', + 'description':'XAPVK7S7OO', + 'display_name':'Project 3', + 'id':319774, + 'is_enabled':True, + 'name':'Project 3', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.594301+00:00' + }, + { + 'approver_user_ids':[ + 'usgybGjChCDu', + None + ], + 'approver_users':[{ + 'email':'approver1@fyleforcad.creatine', + 'full_name':'Ryan Gallagher', + 'id':'usgybGjChCDu' + } + ], + 'category_ids':[ + 253384, + 270947, + 274746, + 274747, + 274748, + 274749, + 274750, + 274751 + ], + 'code':'WA72S4PBT9', + 'created_at':'2023-04-06T06:13:51.104950+00:00', + 'description':'N457NEL6AI', + 'display_name':'Project 2', + 'id':319773, + 'is_enabled':True, + 'name':'Project 2', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.592994+00:00' + }, + { + 'approver_user_ids':[ + 'usgybGjChCDu', + None + ], + 'approver_users':[{ + 'email':'approver1@fyleforcad.creatine', + 'full_name':'Ryan Gallagher', + 'id':'usgybGjChCDu' + } + ], + 'category_ids':[ + 270834, + 274750, + 274751 + ], + 'code':'3HT5DJ2WSM', + 'created_at':'2023-04-06T06:13:50.188270+00:00', + 'description':'B24BLFHB1O', + 'display_name':'Project 1', + 'id':319772, + 'is_enabled':True, + 'name':'Project 1', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-10-31T13:47:49.580002+00:00' + } + ], + 'offset':0 + } + ], + "create_new_auto_create_projects_expense_attributes_1": [ + { + 'count':3, + 'data':[ + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'131', + 'created_at':'2023-11-16T11:41:54.330090+00:00', + 'description':'Sage Intacct Project - wraith squad, Id - 131', + 'display_name':'wraith squad', + 'id':324500, + 'is_enabled':True, + 'name':'wraith squad', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-16T11:41:54.330093+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'237', + 'created_at':'2023-11-19T08:11:33.534201+00:00', + 'description':'Sage Intacct Project - Qwin, Id - 237', + 'display_name':'Qwin', + 'id':324524, + 'is_enabled':True, + 'name':'Qwin', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-19T08:11:33.534206+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'235', + 'created_at':'2023-11-19T08:03:34.144823+00:00', + 'description':'Sage Intacct Project - David, Id - 235', + 'display_name':'David', + 'id':324522, + 'is_enabled':True, + 'name':'David', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-19T08:06:14.246825+00:00' + }, + ], + 'offset':0 + } + ], + "create_new_auto_create_projects_expense_attributes_3": [ + { + 'count':0, + 'data':[], + 'offset':0 + } + ], + "create_new_auto_create_projects_expense_attributes_4": [ + { + 'count':2, + 'data':[ + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'235', + 'created_at':'2023-11-19T08:03:34.144823+00:00', + 'description':'Sage Intacct Project - David, Id - 235', + 'display_name':'David', + 'id':324522, + 'is_enabled':False, + 'name':'David', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-22T08:24:25.138081+00:00' + }, + { + 'approver_user_ids':[ + ], + 'approver_users':[ + ], + 'category_ids':None, + 'code':'237', + 'created_at':'2023-11-19T08:11:33.534201+00:00', + 'description':'Sage Intacct Project - Qwin, Id - 237', + 'display_name':'Qwin', + 'id':324524, + 'is_enabled':False, + 'name':'Qwin', + 'org_id':'or5qYLrvnoF9', + 'restricted_spender_user_ids':None, + 'sub_project':None, + 'updated_at':'2023-11-19T08:11:33.534206+00:00' + }, + ], + 'offset':0 + } + ] +} diff --git a/tests/test_fyle_integrations_imports/test_modules/test_base.py b/tests/test_fyle_integrations_imports/test_modules/test_base.py new file mode 100644 index 00000000..28225f0d --- /dev/null +++ b/tests/test_fyle_integrations_imports/test_modules/test_base.py @@ -0,0 +1,173 @@ +from datetime import ( + datetime, + timezone, + timedelta +) +from fyle_accounting_mappings.models import ( + DestinationAttribute, + ExpenseAttribute, + Mapping +) +from unittest import mock +from apps.workspaces.models import Workspace +from apps.workspaces.models import QBOCredential +from apps.quickbooks_online.utils import QBOConnector +from fyle_integrations_imports.modules.projects import Project +from fyle_integrations_imports.models import ImportLog +from tests.test_fyle_integrations_imports.helpers import ( + get_base_class_instance, + get_platform_connection +) +from tests.test_fyle_integrations_imports.test_modules.fixtures import projects_data + + +def test_remove_duplicates(db): + attributes = DestinationAttribute.objects.filter(attribute_type='CUSTOMER') + + assert len(attributes) == 152 + + for attribute in attributes: + DestinationAttribute.objects.create( + attribute_type='CUSTOMER', + workspace_id=attribute.workspace_id, + value=attribute.value, + destination_id='010{0}'.format(attribute.destination_id) + ) + + attributes = DestinationAttribute.objects.filter(attribute_type='CUSTOMER') + + assert len(attributes) == 304 + + base = get_base_class_instance() + + attributes = base.remove_duplicate_attributes(attributes) + assert len(attributes) == 65 + + +def test_get_platform_class(db): + base = get_base_class_instance() + platform = get_platform_connection(1) + + assert base.get_platform_class(platform) == platform.projects + + base = get_base_class_instance(workspace_id=1, source_field='CATEGORY', destination_field='ACCOUNT', platform_class_name='categories') + assert base.get_platform_class(platform) == platform.categories + + base = get_base_class_instance(workspace_id=1, source_field='COST_CENTER', destination_field='DEPARTMENT', platform_class_name='cost_centers') + assert base.get_platform_class(platform) == platform.cost_centers + + +def test_construct_attributes_filter(db): + base = get_base_class_instance() + + assert base.construct_attributes_filter('PROJECT') == {'attribute_type': 'PROJECT', 'workspace_id': 1} + + date_string = '2023-08-06 12:50:05.875029' + sync_after = datetime.strptime(date_string, '%Y-%m-%d %H:%M:%S.%f') + + base = get_base_class_instance(workspace_id=1, source_field='CATEGORY', destination_field='ACCOUNT', platform_class_name='categories', sync_after=sync_after) + + assert base.construct_attributes_filter('CATEGORY') == {'attribute_type': 'CATEGORY', 'workspace_id': 1, 'updated_at__gte': sync_after} + + paginated_destination_attribute_values = ['Mobile App Redesign', 'Platform APIs', 'Fyle NetSuite Integration', 'Fyle Sage Intacct Integration', 'Support Taxes', 'T&M Project with Five Tasks', 'Fixed Fee Project with Five Tasks', 'General Overhead', 'General Overhead-Current', 'Youtube proj', 'Integrations', 'Yujiro', 'Pickle'] + + assert base.construct_attributes_filter('COST_CENTER', paginated_destination_attribute_values) == {'attribute_type': 'COST_CENTER', 'workspace_id': 1, 'updated_at__gte': sync_after, 'value__in': paginated_destination_attribute_values} + + +def test_expense_attributes_sync_after(db): + project = get_base_class_instance() + + current_time = datetime.now() - timedelta(minutes=300) + sync_after = current_time.replace(tzinfo=timezone.utc) + project.sync_after = sync_after + + expense_attributes = ExpenseAttribute.objects.filter(workspace_id=1, attribute_type='PROJECT')[0:100] + + assert expense_attributes.count() == 100 + + paginated_expense_attribute_values = [] + + for expense_attribute in expense_attributes: + expense_attribute.updated_at = datetime.now().replace(tzinfo=timezone.utc) + expense_attribute.save() + paginated_expense_attribute_values.append(expense_attribute.value) + + filters = project.construct_attributes_filter('PROJECT', paginated_expense_attribute_values) + + expense_attributes = ExpenseAttribute.objects.filter(**filters) + + assert expense_attributes.count() == 100 + + +def test_auto_create_destination_attributes(mocker, db): + workspace_id = 3 + qbo_credentials = QBOCredential.get_active_qbo_credentials(workspace_id) + qbo_connection = QBOConnector(credentials_object=qbo_credentials, workspace_id=workspace_id) + project = Project(3, 'CUSTOMER', None, qbo_connection, 'customers', True) + project.sync_after = None + + Workspace.objects.filter(id=workspace_id).update(fyle_org_id='or5qYLrvnoF9') + + # delete all destination attributes, expense attributes and mappings + Mapping.objects.filter(workspace_id=workspace_id, source_type='PROJECT').delete() + Mapping.objects.filter(workspace_id=workspace_id, destination_type='CUSTOMER').delete() + DestinationAttribute.objects.filter(workspace_id=workspace_id, attribute_type='CUSTOMER').delete() + ExpenseAttribute.objects.filter(workspace_id=workspace_id, attribute_type='PROJECT').delete() + + with mock.patch('fyle.platform.apis.v1beta.admin.Projects.list_all') as mock_call: + mocker.patch( + 'fyle_integrations_platform_connector.apis.Projects.post_bulk', + return_value=[] + ) + mocker.patch( + 'qbosdk.apis.Customers.count', + return_value=41 + ) + mocker.patch( + 'qbosdk.apis.Customers.get', + return_value=projects_data['create_new_auto_create_projects_destination_attributes'] + ) + mock_call.side_effect = [ + projects_data['create_new_auto_create_projects_expense_attributes_0'], + projects_data['create_new_auto_create_projects_expense_attributes_1'] + ] + project.trigger_import() + + # Not creating the schedule part due to time diff + current_time = datetime.now() + sync_after = current_time.replace(tzinfo=timezone.utc) + project.sync_after = sync_after + + import_log = ImportLog.objects.filter(workspace_id=workspace_id).first() + import_log.status = 'COMPLETE' + import_log.attribute_type = 'PROJECT' + import_log.total_batches_count = 10 + import_log.processed_batches_count = 10 + import_log.error_log = [] + import_log.save() + + import_log = ImportLog.objects.filter(workspace_id=workspace_id).first() + + response = project.trigger_import() + + import_log_post_run = ImportLog.objects.filter(workspace_id=workspace_id).first() + + assert response == None + assert import_log.status == import_log_post_run.status + assert import_log.total_batches_count == import_log_post_run.total_batches_count + + # not creating the schedule due to a schedule running already + project.sync_after = None + + import_log = ImportLog.objects.filter(workspace_id=workspace_id).first() + import_log.status = 'IN_PORGRESS' + import_log.total_batches_count = 8 + import_log.processed_batches_count = 3 + import_log.save() + + response = project.trigger_import() + + assert response == None + assert import_log.status == 'IN_PORGRESS' + assert import_log.total_batches_count != 0 + assert import_log.processed_batches_count != 0 diff --git a/tests/test_fyle_integrations_imports/test_modules/test_projects.py b/tests/test_fyle_integrations_imports/test_modules/test_projects.py new file mode 100644 index 00000000..dbf1fc5e --- /dev/null +++ b/tests/test_fyle_integrations_imports/test_modules/test_projects.py @@ -0,0 +1,205 @@ +from unittest import mock +from fyle_accounting_mappings.models import ( + DestinationAttribute, + ExpenseAttribute, + Mapping, +) +from apps.quickbooks_online.utils import QBOConnector +from apps.workspaces.models import QBOCredential, FyleCredential, Workspace +from fyle_integrations_platform_connector import PlatformConnector +from fyle_integrations_imports.modules import Project +from tests.test_fyle_integrations_imports.test_modules.fixtures import projects_data + + +def test_sync_destination_attributes(mocker, db): + workspace_id = 3 + + mocker.patch('qbosdk.apis.Customers.count', return_value=41) + mocker.patch('qbosdk.apis.Customers.get', return_value=projects_data['create_new_auto_create_projects_destination_attributes']) + + qbo_credentials = QBOCredential.get_active_qbo_credentials(workspace_id) + qbo_connection = QBOConnector(credentials_object=qbo_credentials, workspace_id=workspace_id) + + destination_attributes_count = DestinationAttribute.objects.filter(workspace_id=3, attribute_type='CUSTOMER').count() + assert destination_attributes_count == 29 + + project = Project(3, 'CUSTOMER', None, qbo_connection, 'customers', True) + project.sync_destination_attributes() + + destination_attributes_count = DestinationAttribute.objects.filter(workspace_id=3, attribute_type='CUSTOMER').count() + assert destination_attributes_count == 43 + + +def test_sync_expense_atrributes(mocker, db): + workspace_id = 3 + fyle_credentials = FyleCredential.objects.get(workspace_id=workspace_id) + fyle_credentials.workspace.fyle_org_id = 'or5qYLrvnoF9' + fyle_credentials.workspace.save() + platform = PlatformConnector(fyle_credentials=fyle_credentials) + + qbo_credentials = QBOCredential.get_active_qbo_credentials(workspace_id) + qbo_connection = QBOConnector(credentials_object=qbo_credentials, workspace_id=workspace_id) + + mocker.patch( + 'fyle.platform.apis.v1beta.admin.Projects.list_all', + return_value=[] + ) + + projects_count = ExpenseAttribute.objects.filter(workspace_id=workspace_id, attribute_type='PROJECT').count() + assert projects_count == 1222 + + project = Project(3, 'CUSTOMER', None, qbo_connection, 'customers', True) + project.sync_expense_attributes(platform) + + projects_count = ExpenseAttribute.objects.filter(workspace_id=workspace_id, attribute_type='PROJECT').count() + assert projects_count == 1222 + + mocker.patch( + 'fyle.platform.apis.v1beta.admin.Projects.list_all', + return_value=projects_data['create_new_auto_create_projects_expense_attributes_0'] + ) + project.sync_expense_attributes(platform) + + projects_count = ExpenseAttribute.objects.filter(workspace_id=workspace_id, attribute_type='PROJECT').count() + assert projects_count == 1266 + + +def test_auto_create_destination_attributes(mocker, db): + workspace_id = 3 + qbo_credentials = QBOCredential.get_active_qbo_credentials(workspace_id) + qbo_connection = QBOConnector(credentials_object=qbo_credentials, workspace_id=workspace_id) + project = Project(3, 'CUSTOMER', None, qbo_connection, 'customers', True) + project.sync_after = None + + Workspace.objects.filter(id=workspace_id).update(fyle_org_id='or5qYLrvnoF9') + + # delete all destination attributes, expense attributes and mappings + Mapping.objects.filter(workspace_id=workspace_id, source_type='PROJECT').delete() + Mapping.objects.filter(workspace_id=workspace_id, destination_type='CUSTOMER').delete() + DestinationAttribute.objects.filter(workspace_id=workspace_id, attribute_type='CUSTOMER').delete() + ExpenseAttribute.objects.filter(workspace_id=workspace_id, attribute_type='PROJECT').delete() + + # create new case for projects import + with mock.patch('fyle.platform.apis.v1beta.admin.Projects.list_all') as mock_call: + mocker.patch( + 'fyle_integrations_platform_connector.apis.Projects.post_bulk', + return_value=[] + ) + mocker.patch( + 'qbosdk.apis.Customers.count', + return_value=41 + ) + mocker.patch( + 'qbosdk.apis.Customers.get', + return_value=projects_data['create_new_auto_create_projects_destination_attributes'] + ) + mock_call.side_effect = [ + projects_data['create_new_auto_create_projects_expense_attributes_0'], + projects_data['create_new_auto_create_projects_expense_attributes_1'] + ] + + expense_attributes_count = ExpenseAttribute.objects.filter(workspace_id=workspace_id, attribute_type = 'PROJECT').count() + + assert expense_attributes_count == 0 + + mappings_count = Mapping.objects.filter(workspace_id=workspace_id, source_type='PROJECT', destination_type='CUSTOMER').count() + + assert mappings_count == 0 + + project.trigger_import() + + expense_attributes_count = ExpenseAttribute.objects.filter(workspace_id=workspace_id, attribute_type = 'PROJECT').count() + + assert expense_attributes_count == projects_data['create_new_auto_create_projects_expense_attributes_0'][0]['count'] + projects_data['create_new_auto_create_projects_expense_attributes_1'][0]['count'] + + mappings_count = Mapping.objects.filter(workspace_id=workspace_id, source_type='PROJECT', destination_type='CUSTOMER').count() + + assert mappings_count == 41 + + # disable case for project import + with mock.patch('fyle.platform.apis.v1beta.admin.Projects.list_all') as mock_call: + mocker.patch( + 'fyle_integrations_platform_connector.apis.Projects.post_bulk', + return_value=[] + ) + mocker.patch( + 'qbosdk.apis.Customers.count', + return_value=39 + ) + mocker.patch( + 'qbosdk.apis.Customers.get', + return_value=projects_data['create_new_auto_create_projects_destination_attributes_disable_case'] + ) + mock_call.side_effect = [ + projects_data['create_new_auto_create_projects_expense_attributes_3'], + projects_data['create_new_auto_create_projects_expense_attributes_4'] + ] + + destination_attribute = DestinationAttribute.objects.filter(workspace_id=workspace_id, value='David').first() + + assert destination_attribute.active == True + + expense_attribute = ExpenseAttribute.objects.filter(workspace_id=workspace_id, value='David').first() + + assert expense_attribute.active == True + + mapping = Mapping.objects.filter(destination_id=destination_attribute.id).first() + + pre_run_expense_attribute_disabled_count = ExpenseAttribute.objects.filter(workspace_id=workspace_id, active=False, attribute_type='PROJECT').count() + + assert pre_run_expense_attribute_disabled_count == 6 + + # This confirms that mapping is present and both expense_attribute and destination_attribute are active + assert mapping.source_id == expense_attribute.id + + project.trigger_import() + + destination_attribute = DestinationAttribute.objects.filter(workspace_id=workspace_id, value='David').first() + + assert destination_attribute.active == False + + expense_attribute = ExpenseAttribute.objects.filter(workspace_id=workspace_id, value='David').first() + + assert expense_attribute.active == False + + post_run_expense_attribute_disabled_count = ExpenseAttribute.objects.filter(workspace_id=workspace_id, active=False, attribute_type='PROJECT').count() + + assert post_run_expense_attribute_disabled_count == pre_run_expense_attribute_disabled_count + projects_data['create_new_auto_create_projects_expense_attributes_4'][0]['count'] + + # not re-enable case for project import + with mock.patch('fyle.platform.apis.v1beta.admin.Projects.list_all') as mock_call: + mocker.patch( + 'fyle_integrations_platform_connector.apis.Projects.post_bulk', + return_value=[] + ) + mocker.patch( + 'qbosdk.apis.Customers.count', + return_value=41 + ) + # In case of QBO the not re-enable case of destination attribute is same as create new case, the disabled values when re-enabled will only be added + mocker.patch( + 'qbosdk.apis.Customers.get', + return_value=projects_data['create_new_auto_create_projects_destination_attributes'] + ) + mock_call.side_effect = [ + projects_data['create_new_auto_create_projects_expense_attributes_3'], + projects_data['create_new_auto_create_projects_expense_attributes_3'] + ] + + pre_run_destination_attribute_count = DestinationAttribute.objects.filter(workspace_id=workspace_id, attribute_type = 'CUSTOMER', active=False).count() + + assert pre_run_destination_attribute_count == 2 + + pre_run_expense_attribute_count = ExpenseAttribute.objects.filter(workspace_id=workspace_id, attribute_type = 'PROJECT', active=False).count() + + assert pre_run_expense_attribute_count == 8 + + project.trigger_import() + + post_run_destination_attribute_count = DestinationAttribute.objects.filter(workspace_id=workspace_id, attribute_type = 'CUSTOMER', active=False).count() + + assert post_run_destination_attribute_count == pre_run_destination_attribute_count - 2 + + post_run_expense_attribute_count = ExpenseAttribute.objects.filter(workspace_id=workspace_id, attribute_type = 'PROJECT', active=False).count() + + assert pre_run_expense_attribute_count == post_run_expense_attribute_count diff --git a/tests/test_fyle_integrations_imports/test_tasks.py b/tests/test_fyle_integrations_imports/test_tasks.py new file mode 100644 index 00000000..c35b51f9 --- /dev/null +++ b/tests/test_fyle_integrations_imports/test_tasks.py @@ -0,0 +1,45 @@ +from unittest import mock +from fyle_integrations_imports.tasks import trigger_import_via_schedule +from fyle_integrations_imports.models import ImportLog +from apps.workspaces.models import QBOCredential +from tests.test_fyle_integrations_imports.test_modules.fixtures import projects_data + + +def test_trigger_import_via_schedule(mocker, db): + workspace_id = 3 + # delete all the import logs + ImportLog.objects.filter(workspace_id=workspace_id).delete() + credentials = QBOCredential.get_active_qbo_credentials(workspace_id) + with mock.patch('fyle.platform.apis.v1beta.admin.Projects.list_all') as mock_call: + mocker.patch( + 'fyle_integrations_platform_connector.apis.Projects.post_bulk', + return_value=[] + ) + mocker.patch( + 'qbosdk.apis.Customers.count', + return_value=41 + ) + mocker.patch( + 'qbosdk.apis.Customers.get', + return_value=projects_data['create_new_auto_create_projects_destination_attributes'] + ) + mock_call.side_effect = [ + projects_data['create_new_auto_create_projects_expense_attributes_0'], + projects_data['create_new_auto_create_projects_expense_attributes_1'] + ] + + trigger_import_via_schedule( + workspace_id=workspace_id, + destination_field='CUSTOMER', + source_field='PROJECT', + sdk_connection_string='apps.quickbooks_online.utils.QBOConnector', + credentials=credentials, + destination_sync_method='customers', + is_auto_sync_enabled=True, + is_custom= False + ) + + import_logs = ImportLog.objects.filter(workspace_id=workspace_id).first() + + assert import_logs.status == 'COMPLETE' + assert import_logs.attribute_type == 'PROJECT' diff --git a/tests/test_mappings/test_exceptions.py b/tests/test_mappings/test_exceptions.py new file mode 100644 index 00000000..58f0313f --- /dev/null +++ b/tests/test_mappings/test_exceptions.py @@ -0,0 +1,109 @@ +from fyle_integrations_imports.models import ImportLog +from fyle_integrations_imports.modules.projects import Project +from apps.workspaces.models import QBOCredential +from apps.quickbooks_online.utils import QBOConnector +from apps.mappings.exceptions import handle_import_exceptions_v2 +from fyle.platform.exceptions import InternalServerError, InvalidTokenError, WrongParamsError +from qbosdk.exceptions import InvalidTokenError as QBOInvalidTokenError +from qbosdk.exceptions import WrongParamsError as QBOWrongParamsError + + +def test_handle_import_exceptions(db): + workspace_id = 3 + ImportLog.objects.create( + workspace_id=workspace_id, + status = 'IN_PROGRESS', + attribute_type = 'PROJECT', + total_batches_count = 10, + processed_batches_count = 2, + error_log = [] + ) + qbo_credentials = QBOCredential.get_active_qbo_credentials(workspace_id) + qbo_connection = QBOConnector(credentials_object=qbo_credentials, workspace_id=workspace_id) + + import_log = ImportLog.objects.get(workspace_id=workspace_id, attribute_type='PROJECT') + project = Project(workspace_id, 'CUSTOMER', None, qbo_connection, 'customers', True) + + # WrongParamsError + @handle_import_exceptions_v2 + def to_be_decoreated(expense_attribute_instance, import_log): + raise WrongParamsError('This is WrongParamsError') + + to_be_decoreated(project, import_log) + + assert import_log.status == 'FAILED' + assert import_log.error_log['task'] == 'Import PROJECT to Fyle and Auto Create Mappings' + assert import_log.error_log['message'] == 'This is WrongParamsError' + assert import_log.error_log['alert'] == True + + # FyleInvalidTokenError + @handle_import_exceptions_v2 + def to_be_decoreated(expense_attribute_instance, import_log): + raise InvalidTokenError('This is FyleInvalidTokenError') + + to_be_decoreated(project, import_log) + + assert import_log.status == 'FAILED' + assert import_log.error_log['task'] == 'Import PROJECT to Fyle and Auto Create Mappings' + assert import_log.error_log['message'] == 'Invalid Token for fyle' + assert import_log.error_log['alert'] == False + + # InternalServerError + @handle_import_exceptions_v2 + def to_be_decoreated(expense_attribute_instance, import_log): + raise InternalServerError('This is InternalServerError') + + to_be_decoreated(project, import_log) + + assert import_log.status == 'FAILED' + assert import_log.error_log['task'] == 'Import PROJECT to Fyle and Auto Create Mappings' + assert import_log.error_log['message'] == 'Internal server error while importing to Fyle' + assert import_log.error_log['alert'] == True + + # QBOWrongParamsError + @handle_import_exceptions_v2 + def to_be_decoreated(expense_attribute_instance, import_log): + raise QBOWrongParamsError('This is InternalServerError') + + to_be_decoreated(project, import_log) + + assert import_log.status == 'FAILED' + assert import_log.error_log['task'] == 'Import PROJECT to Fyle and Auto Create Mappings' + assert import_log.error_log['message'] == 'Invalid Token or QBO credentials does not exist workspace_id - 3' + assert import_log.error_log['alert'] == False + + # QBOInvalidTokenError + @handle_import_exceptions_v2 + def to_be_decoreated(expense_attribute_instance, import_log): + raise QBOInvalidTokenError('This is InternalServerError') + + to_be_decoreated(project, import_log) + + assert import_log.status == 'FAILED' + assert import_log.error_log['task'] == 'Import PROJECT to Fyle and Auto Create Mappings' + assert import_log.error_log['message'] == 'Invalid Token or QBO credentials does not exist workspace_id - 3' + assert import_log.error_log['alert'] == False + + # QBOCredential.DoesNotExist + @handle_import_exceptions_v2 + def to_be_decoreated(expense_attribute_instance, import_log): + raise QBOCredential.DoesNotExist('This is InternalServerError') + + to_be_decoreated(project, import_log) + + assert import_log.status == 'FAILED' + assert import_log.error_log['task'] == 'Import PROJECT to Fyle and Auto Create Mappings' + assert import_log.error_log['message'] == 'Invalid Token or QBO credentials does not exist workspace_id - 3' + assert import_log.error_log['alert'] == False + + # Exception + @handle_import_exceptions_v2 + def to_be_decoreated(expense_attribute_instance, import_log): + raise Exception('This is a general Exception') + + to_be_decoreated(project, import_log) + + assert import_log.status == 'FATAL' + assert import_log.error_log['task'] == 'Import PROJECT to Fyle and Auto Create Mappings' + assert import_log.error_log['message'] == 'Something went wrong' + assert import_log.error_log['alert'] == False diff --git a/tests/test_mappings/test_queues.py b/tests/test_mappings/test_queues.py new file mode 100644 index 00000000..0e9211a9 --- /dev/null +++ b/tests/test_mappings/test_queues.py @@ -0,0 +1,16 @@ +from apps.mappings.queues import construct_tasks_and_chain_import_fields_to_fyle +from fyle_accounting_mappings.models import MappingSetting + + +def test_construct_tasks_and_chain_import_fields_to_fyle(db): + workspace_id = 3 + MappingSetting.objects.filter(workspace_id=workspace_id).delete() + MappingSetting.objects.create( + source_field='PROJECT', + destination_field='CUSTOMER', + workspace_id=workspace_id, + import_to_fyle=True, + is_custom=False + ) + + construct_tasks_and_chain_import_fields_to_fyle(workspace_id) diff --git a/tests/test_mappings/test_schedules.py b/tests/test_mappings/test_schedules.py new file mode 100644 index 00000000..7c75ba41 --- /dev/null +++ b/tests/test_mappings/test_schedules.py @@ -0,0 +1,35 @@ +from django_q.models import Schedule +from fyle_accounting_mappings.models import MappingSetting +from apps.mappings.schedules import schedule_or_delete_fyle_import_tasks +from apps.workspaces.models import WorkspaceGeneralSettings + + +def test_schedule_creation(db): + workspace_id = 3 + + # Test schedule projects creation + configuration = WorkspaceGeneralSettings.objects.get(workspace_id=workspace_id) + configuration.import_categories = True + configuration.import_projects = True + configuration.import_vendors_as_merchants = True + configuration.import_tax_codes = True + configuration.save() + + MappingSetting.objects.filter(workspace_id=workspace_id).delete() + mapping_setting = MappingSetting.objects.create( + source_field='PROJECT', + destination_field='CUSTOMER', + workspace_id=workspace_id, + import_to_fyle=True, + is_custom=False + ) + + schedule_or_delete_fyle_import_tasks(configuration, mapping_setting) + + schedule = Schedule.objects.filter( + func='apps.mappings.queues.construct_tasks_and_chain_import_fields_to_fyle', + args='{}'.format(workspace_id), + ).first() + + assert schedule.func == 'apps.mappings.queues.construct_tasks_and_chain_import_fields_to_fyle' + assert schedule.args == '3' diff --git a/tests/test_mappings/test_tasks.py b/tests/test_mappings/test_tasks.py index 9759d6c9..29d09909 100644 --- a/tests/test_mappings/test_tasks.py +++ b/tests/test_mappings/test_tasks.py @@ -13,7 +13,7 @@ from fyle_integrations_platform_connector import PlatformConnector from qbosdk.exceptions import WrongParamsError -from apps.mappings.queue import ( +from apps.mappings.queues import ( schedule_auto_map_ccc_employees, schedule_auto_map_employees, schedule_cost_centers_creation, @@ -28,7 +28,6 @@ auto_create_category_mappings, auto_create_cost_center_mappings, auto_create_expense_fields_mappings, - auto_create_project_mappings, auto_create_tax_codes_mappings, auto_create_vendors_as_merchants, auto_import_and_map_fyle_fields, @@ -158,52 +157,6 @@ def test_schedule_tax_groups_creation(db): assert schedule == None -def test_auto_create_project_mappings(db, mocker): - workspace_id = 4 - mocker.patch('fyle_integrations_platform_connector.apis.Projects.sync', return_value=[]) - mocker.patch('fyle_integrations_platform_connector.apis.Projects.post_bulk', return_value=[]) - mocker.patch('qbosdk.apis.Customers.count', return_value=5) - mocker.patch('qbosdk.apis.Customers.get', return_value=[]) - mocker.patch('qbosdk.apis.Departments.get', return_value=[]) - - response = auto_create_project_mappings(workspace_id=workspace_id) - assert response == None - - mapping_setting = MappingSetting.objects.get(source_field='PROJECT', workspace_id=workspace_id) - mapping_setting.destination_field = 'CUSTOMER' - mapping_setting.save() - - expense_attributes_to_enable = ExpenseAttribute.objects.filter(mapping__isnull=False, mapping__source_type='PROJECT', attribute_type='PROJECT', workspace_id=workspace_id).first() - - expense_attributes_to_enable.active = False - expense_attributes_to_enable.save() - - response = auto_create_project_mappings(workspace_id=workspace_id) - assert response == None - - projects = DestinationAttribute.objects.filter(workspace_id=workspace_id, attribute_type='PROJECT').count() - mappings = Mapping.objects.filter(workspace_id=workspace_id, destination_type='PROJECT').count() - - assert mappings == projects - - with mock.patch('fyle_integrations_platform_connector.apis.Projects.sync') as mock_call: - mock_call.side_effect = WrongParamsError(msg='invalid params', response='invalid params') - auto_create_project_mappings(workspace_id=workspace_id) - - mock_call.side_effect = Exception - auto_create_project_mappings(workspace_id=workspace_id) - - mock_call.side_effect = FyleInvalidTokenError(msg='Invalid Token for fyle', response='Invalid Token for fyle') - auto_create_project_mappings(workspace_id=workspace_id) - - fyle_credentials = FyleCredential.objects.get(workspace_id=workspace_id) - fyle_credentials.delete() - - response = auto_create_project_mappings(workspace_id=workspace_id) - - assert response == None - - def test_remove_duplicates(db): attributes = DestinationAttribute.objects.filter(attribute_type='EMPLOYEE') @@ -271,10 +224,10 @@ def test_auto_create_category_mappings(db, mocker): with mock.patch('fyle_integrations_platform_connector.apis.Projects.sync') as mock_call: mock_call.side_effect = WrongParamsError(msg='invalid params', response='invalid params') - auto_create_project_mappings(workspace_id=workspace_id) + auto_create_category_mappings(workspace_id=workspace_id) mock_call.side_effect = FyleInvalidTokenError(msg='Invalid Token for fyle', response='Invalid Token for fyle') - auto_create_project_mappings(workspace_id=workspace_id) + auto_create_category_mappings(workspace_id=workspace_id) fyle_credentials = FyleCredential.objects.get(workspace_id=workspace_id) fyle_credentials.delete() diff --git a/tests/test_quickbooks_online/test_tasks.py b/tests/test_quickbooks_online/test_tasks.py index ac66ea6d..8adfa2ae 100644 --- a/tests/test_quickbooks_online/test_tasks.py +++ b/tests/test_quickbooks_online/test_tasks.py @@ -8,7 +8,7 @@ from qbosdk.exceptions import WrongParamsError from apps.fyle.models import Expense, ExpenseGroup, Reimbursement -from apps.mappings.queue import schedule_bill_payment_creation +from apps.mappings.queues import schedule_bill_payment_creation from apps.quickbooks_online.exceptions import handle_quickbooks_error from apps.quickbooks_online.queue import ( schedule_bills_creation,