Ejemplo n.º 1
0
def auto_create_category_mappings(workspace_id):
    """
    Create Category Mappings
    :return: mappings
    """

    try:
        fyle_categories = upload_categories_to_fyle(workspace_id=workspace_id)

        Mapping.bulk_create_mappings(fyle_categories, 'CATEGORY', 'ACCOUNT',
                                     workspace_id)

        return []

    except WrongParamsError as exception:
        logger.error(
            'Error while creating categories workspace_id - %s in Fyle %s %s',
            workspace_id, exception.message, {'error': exception.response})

    except Exception:
        error = traceback.format_exc()
        error = {'error': error}
        logger.error(
            'Error while creating categories workspace_id - %s error: %s',
            workspace_id, error)
Ejemplo n.º 2
0
def async_auto_map_employees(workspace_id: int):
    configuration = Configuration.objects.get(workspace_id=workspace_id)
    employee_mapping_preference = configuration.auto_map_employees

    mapping_setting = MappingSetting.objects.filter(
        ~Q(destination_field='CREDIT_CARD_ACCOUNT'),
        source_field='EMPLOYEE',
        workspace_id=workspace_id).first()
    destination_type = mapping_setting.destination_field

    fyle_credentials = FyleCredential.objects.get(workspace_id=workspace_id)
    fyle_connection = FyleConnector(
        refresh_token=fyle_credentials.refresh_token,
        workspace_id=workspace_id)

    netsuite_credentials = NetSuiteCredentials.objects.get(
        workspace_id=workspace_id)
    netsuite_connection = NetSuiteConnector(
        netsuite_credentials=netsuite_credentials, workspace_id=workspace_id)

    fyle_connection.sync_employees()
    if destination_type == 'EMPLOYEE':
        netsuite_connection.sync_employees()
    else:
        netsuite_connection.sync_vendors()

    Mapping.auto_map_employees(destination_type, employee_mapping_preference,
                               workspace_id)
Ejemplo n.º 3
0
def async_auto_map_employees(workspace_id: int):
    try:
        employee_mapping_preference = WorkspaceGeneralSettings.objects.get(
            workspace_id=workspace_id).auto_map_employees

        fyle_credentials = FyleCredential.objects.get(
            workspace_id=workspace_id)
        fyle_connection = FyleConnector(
            refresh_token=fyle_credentials.refresh_token,
            workspace_id=workspace_id)

        xero_credentials = XeroCredentials.objects.get(
            workspace_id=workspace_id)
        xero_connection = XeroConnector(xero_credentials,
                                        workspace_id=workspace_id)

        fyle_connection.sync_employees()
        xero_connection.sync_contacts()

        Mapping.auto_map_employees('CONTACT', employee_mapping_preference,
                                   workspace_id)

    except XeroCredentials.DoesNotExist:
        logger.error(
            'Xero Credentials not found for workspace_id %s',
            workspace_id,
        )
Ejemplo n.º 4
0
def post_projects_in_batches(fyle_connection: FyleConnector,
                             workspace_id: int):
    existing_project_names = ExpenseAttribute.objects.filter(
        attribute_type='PROJECT',
        workspace_id=workspace_id).values_list('value', flat=True)
    ns_attributes_count = DestinationAttribute.objects.filter(
        attribute_type='PROJECT', workspace_id=workspace_id).count()
    page_size = 200

    for offset in range(0, ns_attributes_count, page_size):
        limit = offset + page_size
        paginated_ns_attributes = DestinationAttribute.objects.filter(
            attribute_type='PROJECT',
            workspace_id=workspace_id).order_by('value', 'id')[offset:limit]

        paginated_ns_attributes = remove_duplicates(paginated_ns_attributes)

        fyle_payload: List[Dict] = create_fyle_projects_payload(
            paginated_ns_attributes, existing_project_names, workspace_id)
        if fyle_payload:
            fyle_connection.connection.Projects.post(fyle_payload)
            fyle_connection.sync_projects()

        Mapping.bulk_create_mappings(paginated_ns_attributes, 'PROJECT',
                                     'PROJECT', workspace_id)
Ejemplo n.º 5
0
def async_auto_map_employees(workspace_id: int):
    general_settings = WorkspaceGeneralSettings.objects.get(
        workspace_id=workspace_id)
    employee_mapping_preference = general_settings.auto_map_employees

    mapping_setting = MappingSetting.objects.filter(
        ~Q(destination_field='CREDIT_CARD_ACCOUNT'),
        source_field='EMPLOYEE',
        workspace_id=workspace_id).first()
    destination_type = mapping_setting.destination_field

    fyle_credentials = FyleCredential.objects.get(workspace_id=workspace_id)
    fyle_connection = FyleConnector(
        refresh_token=fyle_credentials.refresh_token,
        workspace_id=workspace_id)

    qbo_credentials = QBOCredential.objects.get(workspace_id=workspace_id)
    qbo_connection = QBOConnector(credentials_object=qbo_credentials,
                                  workspace_id=workspace_id)

    fyle_connection.sync_employees()
    if destination_type == 'EMPLOYEE':
        qbo_connection.sync_employees()
    else:
        qbo_connection.sync_vendors()

    Mapping.auto_map_employees(destination_type, employee_mapping_preference,
                               workspace_id)
Ejemplo n.º 6
0
def async_auto_map_ccc_account(workspace_id: int):
    general_mappings = GeneralMapping.objects.get(workspace_id=workspace_id)
    default_ccc_account_id = general_mappings.default_ccc_account_id

    fyle_credentials = FyleCredential.objects.get(workspace_id=workspace_id)
    fyle_connection = FyleConnector(
        refresh_token=fyle_credentials.refresh_token,
        workspace_id=workspace_id)
    fyle_connection.sync_employees()

    Mapping.auto_map_ccc_employees('CREDIT_CARD_ACCOUNT',
                                   default_ccc_account_id, workspace_id)
Ejemplo n.º 7
0
def auto_create_category_mappings(workspace_id):
    """
    Create Category Mappings
    :return: mappings
    """
    configuration: Configuration = Configuration.objects.get(
        workspace_id=workspace_id)

    reimbursable_expenses_object = configuration.reimbursable_expenses_object
    corporate_credit_card_expenses_object = configuration.corporate_credit_card_expenses_object

    if reimbursable_expenses_object == 'EXPENSE REPORT':
        reimbursable_destination_type = 'EXPENSE_CATEGORY'
    else:
        reimbursable_destination_type = 'ACCOUNT'

    try:
        fyle_categories = upload_categories_to_fyle(
            workspace_id=workspace_id,
            reimbursable_expenses_object=reimbursable_expenses_object)

        Mapping.bulk_create_mappings(fyle_categories, 'CATEGORY',
                                     reimbursable_destination_type,
                                     workspace_id)

        if corporate_credit_card_expenses_object:
            create_credit_card_category_mappings(
                reimbursable_expenses_object,
                corporate_credit_card_expenses_object, workspace_id)

        return []
    except WrongParamsError as exception:
        logger.error(
            'Error while creating categories workspace_id - %s in Fyle %s %s',
            workspace_id, exception.message, {'error': exception.response})
    except Exception:
        error = traceback.format_exc()
        error = {'error': error}
        logger.error(
            'Error while creating categories workspace_id - %s error: %s',
            workspace_id, error)
Ejemplo n.º 8
0
def create_or_update_employee_mapping(expense_group: ExpenseGroup,
                                      qbo_connection: QBOConnector,
                                      auto_map_employees_preference: str):
    try:
        Mapping.objects.get(
            destination_type='VENDOR',
            source_type='EMPLOYEE',
            source__value=expense_group.description.get('employee_email'),
            workspace_id=expense_group.workspace_id)
    except Mapping.DoesNotExist:
        source_employee = ExpenseAttribute.objects.get(
            workspace_id=expense_group.workspace_id,
            attribute_type='EMPLOYEE',
            value=expense_group.description.get('employee_email'))

        try:
            if auto_map_employees_preference == 'EMAIL':
                filters = {
                    'detail__email__iexact': source_employee.value,
                    'attribute_type': 'VENDOR'
                }

            else:
                filters = {
                    'value__iexact': source_employee.detail['full_name'],
                    'attribute_type': 'VENDOR'
                }

            entity = DestinationAttribute.objects.filter(
                workspace_id=expense_group.workspace_id, **filters).first()

            if entity is None:
                entity: DestinationAttribute = qbo_connection.get_or_create_vendor(
                    vendor_name=source_employee.detail['full_name'],
                    email=source_employee.value,
                    create=True)

            mapping = Mapping.create_or_update_mapping(
                source_type='EMPLOYEE',
                source_value=expense_group.description.get('employee_email'),
                destination_type='VENDOR',
                destination_id=entity.destination_id,
                destination_value=entity.value,
                workspace_id=int(expense_group.workspace_id))

            mapping.source.auto_mapped = True
            mapping.source.save()

            mapping.destination.auto_created = True
            mapping.destination.save()
        except WrongParamsError as bad_request:
            logger.error(bad_request.response)

            error_response = json.loads(
                bad_request.response)['Fault']['Error'][0]

            # This error code comes up when the vendor or employee already exists
            if error_response['code'] == '6240':
                logger.error(
                    'Destination Attribute with value %s not found in workspace %s',
                    source_employee.detail['full_name'],
                    expense_group.workspace_id)
Ejemplo n.º 9
0
def create_or_update_employee_mapping(expense_group: ExpenseGroup,
                                      netsuite_connection: NetSuiteConnector,
                                      auto_map_employees_preference: str):
    try:
        Mapping.objects.get(
            Q(destination_type='VENDOR') | Q(destination_type='EMPLOYEE'),
            source_type='EMPLOYEE',
            source__value=expense_group.description.get('employee_email'),
            workspace_id=expense_group.workspace_id)
    except Mapping.DoesNotExist:
        employee_mapping_setting = MappingSetting.objects.filter(
            Q(destination_field='VENDOR') | Q(destination_field='EMPLOYEE'),
            source_field='EMPLOYEE',
            workspace_id=expense_group.workspace_id).first().destination_field

        source_employee = ExpenseAttribute.objects.get(
            workspace_id=expense_group.workspace_id,
            attribute_type='EMPLOYEE',
            value=expense_group.description.get('employee_email'))

        try:
            filters = {}

            if auto_map_employees_preference == 'EMAIL':
                filters = {
                    'detail__email__iexact': source_employee.value,
                    'attribute_type': employee_mapping_setting
                }

            elif auto_map_employees_preference == 'NAME':
                filters = {
                    'value__iexact': source_employee.detail['full_name'],
                    'attribute_type': employee_mapping_setting
                }

            created_entity = DestinationAttribute.objects.filter(
                workspace_id=expense_group.workspace_id, **filters).first()

            if employee_mapping_setting == 'EMPLOYEE':
                if created_entity is None:
                    created_entity: DestinationAttribute = netsuite_connection.get_or_create_employee(
                        source_employee, expense_group)

            else:
                if created_entity is None:
                    created_entity: DestinationAttribute = netsuite_connection.get_or_create_vendor(
                        source_employee, expense_group)

            mapping = Mapping.create_or_update_mapping(
                source_type='EMPLOYEE',
                source_value=expense_group.description.get('employee_email'),
                destination_type=employee_mapping_setting,
                destination_id=created_entity.destination_id,
                destination_value=created_entity.value,
                workspace_id=int(expense_group.workspace_id))

            mapping.source.auto_mapped = True
            mapping.source.save()

            mapping.destination.auto_created = True
            mapping.destination.save()

        except NetSuiteRequestError as exception:
            logger.exception({'error': exception})
Ejemplo n.º 10
0
def create_credit_card_category_mappings(reimbursable_expenses_object,
                                         corporate_credit_card_expenses_object,
                                         workspace_id):
    """
    Create credit card mappings
    """
    mapping_batch = []
    category_mappings = Mapping.objects.filter(
        source_id__in=Mapping.objects.filter(
            workspace_id=workspace_id, source_type='CATEGORY').values(
                'source_id').annotate(count=Count('source_id')).filter(
                    count=1).values_list('source_id'))

    if reimbursable_expenses_object == 'EXPENSE REPORT' and corporate_credit_card_expenses_object == 'EXPENSE REPORT':
        destination_type = 'CCC_EXPENSE_CATEGORY'
    else:
        destination_type = 'CCC_ACCOUNT'

    destination_values = []
    account_internal_ids = []
    for mapping in category_mappings:
        destination_values.append(mapping.destination.value)
        if mapping.destination.detail and 'account_internal_id' in mapping.destination.detail:
            account_internal_ids.append(
                mapping.destination.detail['account_internal_id'])

    if reimbursable_expenses_object == 'EXPENSE REPORT' and corporate_credit_card_expenses_object in (
            'BILL', 'JOURNAL ENTRY', 'CREDIT CARD CHARGE'):
        destination_attributes = DestinationAttribute.objects.filter(
            workspace_id=workspace_id,
            attribute_type=destination_type,
            destination_id__in=account_internal_ids).all()
    else:
        destination_attributes = DestinationAttribute.objects.filter(
            workspace_id=workspace_id,
            attribute_type=destination_type,
            value__in=destination_values).all()

    destination_id_map = {}
    for attribute in destination_attributes:
        destination_id_map[attribute.value] = {
            'id': attribute.id,
            'destination_id': attribute.destination_id
        }

    for mapping in category_mappings:
        if reimbursable_expenses_object == 'EXPENSE REPORT':
            if corporate_credit_card_expenses_object == 'EXPENSE REPORT':
                mapping_batch.append(
                    Mapping(source_type='CATEGORY',
                            destination_type=destination_type,
                            source_id=mapping.source.id,
                            destination_id=destination_id_map[
                                mapping.destination.value]['id'],
                            workspace_id=workspace_id))
            elif corporate_credit_card_expenses_object in (
                    'BILL', 'JOURNAL ENTRY', 'CREDIT CARD CHARGE'):
                for value in destination_id_map:
                    if destination_id_map[value][
                            'destination_id'] == mapping.destination.detail[
                                'account_internal_id']:
                        mapping_batch.append(
                            Mapping(
                                source_type='CATEGORY',
                                destination_type=destination_type,
                                source_id=mapping.source.id,
                                destination_id=destination_id_map[value]['id'],
                                workspace_id=workspace_id))
                        break

        elif reimbursable_expenses_object in ('BILL', 'JOURNAL ENTRY'):
            mapping_batch.append(
                Mapping(source_type='CATEGORY',
                        destination_type=destination_type,
                        source_id=mapping.source.id,
                        destination_id=destination_id_map[
                            mapping.destination.value]['id'],
                        workspace_id=workspace_id))

    if mapping_batch:
        Mapping.objects.bulk_create(mapping_batch, batch_size=50)