From 5eaa7dd0d1ad591c89aba12b2c58b3e8b21f1352 Mon Sep 17 00:00:00 2001 From: Shreyansh Sahare Date: Mon, 9 Sep 2024 22:33:30 +0530 Subject: [PATCH 01/25] Added spotlight app --- apps/spotlight/__init__.py | 0 apps/spotlight/admin.py | 3 +++ apps/spotlight/apps.py | 5 +++++ apps/spotlight/migrations/__init__.py | 0 apps/spotlight/models.py | 3 +++ apps/spotlight/tests.py | 3 +++ apps/spotlight/urls.py | 20 ++++++++++++++++++++ apps/spotlight/views.py | 3 +++ 8 files changed, 37 insertions(+) create mode 100644 apps/spotlight/__init__.py create mode 100644 apps/spotlight/admin.py create mode 100644 apps/spotlight/apps.py create mode 100644 apps/spotlight/migrations/__init__.py create mode 100644 apps/spotlight/models.py create mode 100644 apps/spotlight/tests.py create mode 100644 apps/spotlight/urls.py create mode 100644 apps/spotlight/views.py diff --git a/apps/spotlight/__init__.py b/apps/spotlight/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/apps/spotlight/admin.py b/apps/spotlight/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/apps/spotlight/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/apps/spotlight/apps.py b/apps/spotlight/apps.py new file mode 100644 index 0000000..b227fb3 --- /dev/null +++ b/apps/spotlight/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class SpotlightConfig(AppConfig): + name = 'spotlight' diff --git a/apps/spotlight/migrations/__init__.py b/apps/spotlight/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/apps/spotlight/models.py b/apps/spotlight/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/apps/spotlight/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/apps/spotlight/tests.py b/apps/spotlight/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/apps/spotlight/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/apps/spotlight/urls.py b/apps/spotlight/urls.py new file mode 100644 index 0000000..9ddefb6 --- /dev/null +++ b/apps/spotlight/urls.py @@ -0,0 +1,20 @@ +"""quickbooks_desktop_api URL Configuration +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/3.0/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: path('', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') +Including another URLconf + 1. Import the include() function: from django.urls import include, path + 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) +""" +from django.urls import path + + + +urlpatterns = [ +] diff --git a/apps/spotlight/views.py b/apps/spotlight/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/apps/spotlight/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. From a58b8d2104b2154066fd5b1e36b56e72db295a03 Mon Sep 17 00:00:00 2001 From: Shreyansh Sahare Date: Tue, 10 Sep 2024 00:52:38 +0530 Subject: [PATCH 02/25] added files for spotlight --- apps/spotlight/llm.py | 96 +++++++++++++++++++++++++ apps/spotlight/prompts/__init__.py | 0 apps/spotlight/prompts/support_genie.py | 12 ++++ apps/spotlight/service.py | 33 +++++++++ docker-compose.yml.template | 5 ++ requirements.txt | 3 + 6 files changed, 149 insertions(+) create mode 100644 apps/spotlight/llm.py create mode 100644 apps/spotlight/prompts/__init__.py create mode 100644 apps/spotlight/prompts/support_genie.py create mode 100644 apps/spotlight/service.py diff --git a/apps/spotlight/llm.py b/apps/spotlight/llm.py new file mode 100644 index 0000000..6cfb327 --- /dev/null +++ b/apps/spotlight/llm.py @@ -0,0 +1,96 @@ +import os +import boto3 +import openai +import json +from typing import Dict + + +AWS_REGION = os.environ["AWS_REGION"] +AWS_ACCESS_KEY_ID = os.environ["AWS_ACCESS_KEY_ID"] +AWS_SECRET_ACCESS_KEY = os.environ["AWS_SECRET_ACCESS_KEY"] + +OPENAI_API_KEY = os.environ["OPENAI_API_KEY"] +KNOWLEDGE_BASE_ID = os.environ["KNOWLEDGE_BASE_ID"] + + +bedrock_session = boto3.Session( + region_name=AWS_REGION, + aws_access_key_id=AWS_ACCESS_KEY_ID, + aws_secret_access_key=AWS_SECRET_ACCESS_KEY +) + +openai_client = openai.OpenAI( + api_key=OPENAI_API_KEY, + max_retries=5, + timeout=10 +) + + +def get_openai_response(*, system_prompt: str) -> dict: + try: + chat_completion_resp = openai_client.chat.completions.create( + model="gpt-4o", + response_format={ + "type": "json_object" + }, + messages=[ + {"role": "system", "content": system_prompt} + ], + temperature=0, + max_tokens=256, + top_p=0, + frequency_penalty=0, + presence_penalty=0 + ) + + return json.loads( + chat_completion_resp.choices[0].message.content + ) + + except (openai.OpenAIError, json.JSONDecodeError) as e: + raise Exception(message=str(e)) + + + +def get_support_response_from_bedrock(*, prompt_template: str, input_message: str) -> Dict: + try: + bedrock_agent_runtime_client = bedrock_session.client( + 'bedrock-agent-runtime' + ) + + response = bedrock_agent_runtime_client.retrieve_and_generate( + input={ + 'text': input_message + }, + retrieveAndGenerateConfiguration={ + 'type': 'KNOWLEDGE_BASE', + 'knowledgeBaseConfiguration': { + 'knowledgeBaseId': KNOWLEDGE_BASE_ID, + 'modelArn': 'arn:aws:bedrock:ap-south-1::foundation-model/anthropic.claude-3-sonnet-20240229-v1:0', + 'generationConfiguration': { + 'inferenceConfig': { + 'textInferenceConfig': { + 'maxTokens': 2048, + 'stopSequences': [], + 'temperature': 0, + 'topP': 1 + } + }, + 'promptTemplate': { + 'textPromptTemplate': prompt_template + } + }, + 'retrievalConfiguration': { + 'vectorSearchConfiguration': { + 'numberOfResults': 5, + 'overrideSearchType': 'HYBRID', + } + } + } + } + ) + + return response + + except json.JSONDecodeError as e: + print(e) diff --git a/apps/spotlight/prompts/__init__.py b/apps/spotlight/prompts/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/apps/spotlight/prompts/support_genie.py b/apps/spotlight/prompts/support_genie.py new file mode 100644 index 0000000..0abfcbd --- /dev/null +++ b/apps/spotlight/prompts/support_genie.py @@ -0,0 +1,12 @@ +PROMPT = """ +You are a question-answering agent. Your task is to answer the user's question using only the information available in the provided search results. +Instructions: +1. The user will ask a question, and you must respond based solely on the information contained in the search results. +2. If the search results do not contain the information needed to answer the question, clearly state that an exact answer could not be found. +3. Do not assume that any assertion made by the user is true. Always verify the user's claims against the search results before including them in your response. +4. Your response must be factual and should only include information directly supported by the search results. Avoid making any assumptions or providing information not present in the documents. +5. Always respond in the third person. +Here are the search results in numbered order: +$search_results$ +$output_format_instructions$ +""" diff --git a/apps/spotlight/service.py b/apps/spotlight/service.py new file mode 100644 index 0000000..d3d4d97 --- /dev/null +++ b/apps/spotlight/service.py @@ -0,0 +1,33 @@ +import llm +from typing import Dict +from prompts.support_genie import PROMPT as SUPPORT_GENIE_PROMPT + +class HelpService: + @classmethod + def extract_citations(cls, *, citations: list) -> list: + urls = set() + for citation in citations: + for reference in citation["retrievedReferences"]: + urls.add(reference['location']['webLocation']['url']) + return list(urls) + + @classmethod + def format_response(cls, *, response: Dict) -> str: + # Extract citations + citations = cls.extract_citations(citations=response["citations"]) + + # Format response + formatted_response = response["output"]["text"] + if citations: + formatted_response = formatted_response + "\n\n*Sources:*\n" + "\n".join(citations) + + return formatted_response + + @classmethod + def get_support_response(cls, *, user_query: str) -> str: + response = llm.get_support_response_from_bedrock( + prompt_template=SUPPORT_GENIE_PROMPT, + input_message=user_query + ) + + return cls.format_response(response=response) diff --git a/docker-compose.yml.template b/docker-compose.yml.template index 7ba0d76..66aa1cc 100644 --- a/docker-compose.yml.template +++ b/docker-compose.yml.template @@ -25,6 +25,11 @@ services: DB_PASSWORD: postgres DB_HOST: db DB_PORT: 5432 + AWS_REGION: '' + AWS_ACCESS_KEY_ID: '' + AWS_SECRET_ACCESS_KEY: '' + OPENAI_API_KEY: '' + KNOWLEDGE_BASE_ID: '' worker: entrypoint: python manage.py qcluster restart: unless-stopped diff --git a/requirements.txt b/requirements.txt index d6669a8..0ade997 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,6 @@ +# boto client for using bedrock +boto3==1.35.14 + # Croniter package for djangoq croniter==1.3.8 From 582d8f77dcc25ef2ceae2669bcf2e576abd5e4f8 Mon Sep 17 00:00:00 2001 From: Shreyansh Sahare Date: Tue, 10 Sep 2024 11:00:03 +0530 Subject: [PATCH 03/25] added queries model --- apps/spotlight/models.py | 20 ++++++++++++++++++++ quickbooks_desktop_api/settings.py | 3 ++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/apps/spotlight/models.py b/apps/spotlight/models.py index 71a8362..6186d34 100644 --- a/apps/spotlight/models.py +++ b/apps/spotlight/models.py @@ -1,3 +1,23 @@ from django.db import models +from django.contrib.auth import get_user_model + + +User = get_user_model() + # Create your models here. +class Query(models.Model): + id = models.AutoField(primary_key=True) + query = models.TextField() + workspace_id = models.IntegerField(help_text="Workspace id of the organization") + _llm_response = models.JSONField(default={}) + user = models.ForeignKey(User, on_delete=models.CASCADE, help_text='Reference to users table') + created_at = models.DateTimeField( + auto_now_add=True, help_text="Created at datetime" + ) + updated_at = models.DateTimeField( + auto_now=True, help_text="Updated at datetime" + ) + + class Meta: + db_table = 'queries' diff --git a/quickbooks_desktop_api/settings.py b/quickbooks_desktop_api/settings.py index d7579ca..b6907c9 100644 --- a/quickbooks_desktop_api/settings.py +++ b/quickbooks_desktop_api/settings.py @@ -59,7 +59,8 @@ 'apps.fyle', 'apps.tasks', 'apps.qbd', - 'apps.mappings' + 'apps.mappings', + 'apps.spotlight' ] MIDDLEWARE = [ From efe0247ed15ff8ecabfa8bc94ee71b72cbc2e95b Mon Sep 17 00:00:00 2001 From: Shreyansh Sahare Date: Tue, 10 Sep 2024 11:00:24 +0530 Subject: [PATCH 04/25] added queries model --- apps/spotlight/migrations/0001_initial.py | 32 +++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 apps/spotlight/migrations/0001_initial.py diff --git a/apps/spotlight/migrations/0001_initial.py b/apps/spotlight/migrations/0001_initial.py new file mode 100644 index 0000000..c8af03b --- /dev/null +++ b/apps/spotlight/migrations/0001_initial.py @@ -0,0 +1,32 @@ +# Generated by Django 3.1.14 on 2024-09-10 05:28 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Query', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('query', models.TextField()), + ('workspace_id', models.IntegerField(help_text='Workspace id of the organization')), + ('_llm_response', models.JSONField(default={})), + ('created_at', models.DateTimeField(auto_now_add=True, help_text='Created at datetime')), + ('updated_at', models.DateTimeField(auto_now=True, help_text='Updated at datetime')), + ('user', models.ForeignKey(help_text='Reference to users table', on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'db_table': 'queries', + }, + ), + ] From c18581cd47d66f5c96db0ac7842a99c2da37d35b Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Tue, 10 Sep 2024 17:33:41 +0530 Subject: [PATCH 05/25] Add spotlight prompt --- apps/spotlight/prompts/spotlight_prompt.py | 406 +++++++++++++++++++++ 1 file changed, 406 insertions(+) create mode 100644 apps/spotlight/prompts/spotlight_prompt.py diff --git a/apps/spotlight/prompts/spotlight_prompt.py b/apps/spotlight/prompts/spotlight_prompt.py new file mode 100644 index 0000000..5ca2e3d --- /dev/null +++ b/apps/spotlight/prompts/spotlight_prompt.py @@ -0,0 +1,406 @@ +PROMPT = """ +You are an AI assistant for integrations usage in expense management application. Your role is to interpret user searches and provide relevant suggestions in a JSON format. Use the following guidelines: + +1. Analyze the user's search query to determine the context and intent. +2. Based on the search, provide up to four relevant suggestions that may include: + - Action: Suggest a task the user can perform + - Navigation: Navigate user to a page related to user's query + - Help: Offer guidance or explanations +3. Choose Action, Navigation and Help suggestions from the map given below for each. +4. Ensure that the suggestions are relevant to the user's search query and provide actionable or informative options. +5. If a query is ambiguous, prioritize the most likely interpretations. +6. IMPORTANT: If the user's search query does not match any specific actions, navigations, or help suggestions, return an empty Array for each key. +6. IMPORTANT: Be very specific regarding the actions you give, only choose actions from the examples given below. +7. Format your response as a JSON object with the following structure: + { + "search": "user's search query", + "suggestions": { + "actions" : [ + { + "code": "unique code for the action", + "title": "suggest title" + "description": "brief description of the suggestion" + }, + // ... up to two actions + ], + "navigations": [ + { + "code": "unique code for the navigation", + "title": "suggest title" + "description": "brief description of the suggestion" + }, + // ... up to two navigations + ], + "help": [ + { + "code": "unique code for the help", + "title": "suggest title" + "description": "brief description of the suggestion" + }, + // ... up to two help suggestions + ] + } + } + +"actions" : [ + { + "code": "trigger_export", + "title": "Export IIF file", + "description": "Export the current data to an IIF file." + }, + { + "code": "apply_date_filter", + "title": "Apply date filter to IIF files", + "description": "Filter IIF files by a specified date range for better visibility." + }, + { + "code": "toggle_export_settings", + "title": "Enable/disable export settings", + "description": "Toggle the export settings to enable or disable export functionality." + }, + { + "code": "select_export_module", + "title": "Select export module", + "description": "Choose the specific module for exporting data." + }, + { + "code": "set_purchased_from_field", + "title": "Set 'Purchased From' field for credit card", + "description": "Map the 'Purchased From' field to the credit card account name." + }, + { + "code": "update_field_mappings", + "title": "Update 'Purchased From' field mappings", + "description": "Modify the current mapping for the 'Purchased From' field." + }, + { + "code": "set_automatic_export_settings", + "title": "Set/Update automatic export settings", + "description": "Configure the automatic export settings for scheduled exports." + }, + { + "code": "set_memo_field", + "title": "Set/Update memo field for exports", + "description": "Configure the memo field for exported data to include relevant details." + }, + { + "code": "map_fields", + "title": "Map Fyle fields to QBD fields", + "description": "Configure the mapping of one field to another for iif export." + }, + { + "code": "create_field_mapping", + "title": "Create/update new field mapping settings", + "description": "Set up a new field mapping for data import/export." + } +] + +"navigations": [ + { + "code": "go_to_dashboard", + "title": "Go to Dashboard", + "description": "Navigate to the IIF file management section for import/export options." + }, + { + "code": "go_to_settings", + "title": "Go to Export Settings", + "description": "Navigate to the export settings section to manage export configurations." + }, + { + "code": "go_to_field_mappings", + "title": "Go to Field Mappings", + "description": "Navigate to the Field Mapping Settings Section to manage Field Mapping Settings." + }, + { + "code": "go_to_advanced_settings", + "title": "Go to Advanced Settings", + "description": "Navigate to the advanced settings section to manage automatic export settings." + }, + { + "code": "go_to_mappings", + "title": "Go to Mappings Page", + "description": "Navigate to the field mapping section to configure mappings." + } +] + +"help": [ + { + "code": "learn_export", + "title": "Learn more about IIF export", + "description": "Get detailed instructions on how to export IIF files." + }, + { + "code": "date_filter_help", + "title": "How to filter IIF files by date", + "description": "Learn how to apply date filters when working with IIF files." + }, + { + "code": "learn_export_settings", + "title": "Learn more about export settings", + "description": "Understand how to manage and configure export settings." + }, + { + "code": "configure_credit_card_mapping", + "title": "How to configure credit card mapping", + "description": "Learn how to set up field mappings for credit card transactions." + }, + { + "code": "field_mapping_help", + "title": "How to create field mappings", + "description": "Learn how to create new field mappings for import/export." + }, + { + "code": "automatic_export_help", + "title": "How to set up automatic export", + "description": "Learn how to configure automatic export settings for your data." + }, + { + "code": "memo_field_help", + "title": "How to use memo field in export", + "description": "Learn how to properly set and use the memo field in data exports." + }, + { + "code": "map_fields_help", + "title": "How to map fields", + "description": "Learn how to map fields for accurate data handling and export." + } +] + + +Examples: +1. User Input Options: ["import and export IIF files", "export"] + Output: + { + "suggestions": { + "actions" : [ + { + "code": "trigger_export", + "title": "Export IIF file", + "description": "Export the current data to an IIF file." + } + ], + "navigations": [ + { + "code": "go_to_dashboard", + "title": "Go to Dashboard", + "description": "Navigate to the IIF file management section for import/export options." + } + ], + "help": [ + { + "code": "learn_export", + "title": "Learn more about IIF export", + "description": "Get detailed instructions on how to export IIF files." + } + ] + } + } + +2. User Input Options: ["filter IIF files by date", "date filter", "filter"] + Output: + { + "suggestions": { + "actions" : [ + { + "code": "apply_date_filter", + "title": "Apply date filter to IIF files", + "description": "Filter IIF files by a specified date range for better visibility." + } + ], + "help": [ + { + "code": "date_filter_help", + "title": "How to filter IIF files by date", + "description": "Learn how to apply date filters when working with IIF files." + } + ], + "navigations": [ + { + "code": "go_to_dashboard", + "title": "Go to Dashboard", + "description": "Go to the Dashboard where IIF export is listed." + } + ] + } + } + +3. User Input Options: ["update export settings", "export settings", "Settings"] + Output: + { + "suggestions": { + "actions" : [ + { + "code": "toggle_export_settings", + "title": "Enable/disable export settings", + "description": "Toggle the export settings to enable or disable export functionality." + }, + { + "code": "select_export_module", + "title": "Select export module", + "description": "Choose the specific module for exporting data." + } + ], + "help": [ + { + "code": "learn_export_settings", + "title": "Learn more about export settings", + "description": "Understand how to manage and configure export settings." + } + ], + "navigations": [ + { + "code": "go_to_settings", + "title": "Go to Export Settings", + "description": "Navigate to the export settings section to manage export configurations." + } + ] + } + } + +4. User Input: "set purchased from field for credit card" + Output: + { + "suggestions": { + "actions" : [ + { + "code": "set_purchased_from_field", + "title": "Set 'Purchased From' field for credit card", + "description": "Map the 'Purchased From' field to the credit card account name." + }, + { + "code": "update_field_mappings", + "title": "Update 'Purchased From' field mappings", + "description": "Modify the current mapping for the 'Purchased From' field." + } + ], + "help": [ + { + "code": "configure_credit_card_mapping", + "title": "How to configure credit card mapping", + "description": "Learn how to set up field mappings for credit card transactions." + } + ] + "navigations": [ + { + "code": "go_to_settings", + "title": "Go to Export Settings", + "description": "Navigate to the export settings section to manage export configurations." + } + ] + } + } + +5. User Input: "create or update field mappings settings" + Output: + { + "suggestions": { + "actions" : [ + { + "code": "create_field_mapping", + "title": "Create/update new field mapping settings", + "description": "Set up a new field mapping for data import/export." + } + ], + "navigations": [ + { + "code": "go_to_field_mappings", + "title": "Go to Field Mappings", + "description": "Navigate to the Field Mapping Settings Section to manage Field Mapping Settings." + } + ], + "help": [ + { + "code": "field_mapping_help", + "title": "How to create field mappings", + "description": "Learn how to create new field mappings for import/export." + } + ] + } + } + + +6. User Input: "update automatic export" + Output: + { + "suggestions": { + "actions" : [ + { + "code": "set_automatic_export_settings", + "title": "Set/Update automatic export settings", + "description": "Configure the automatic export settings for scheduled exports." + } + ], + "navigations": [ + { + "code": "go_to_advanced_settings", + "title": "Go to Advanced Settings", + "description": "Navigate to the advanced settings section to manage automatic export settings." + } + ], + "help": [ + { + "code": "automatic_export_help", + "title": "How to set up automatic export", + "description": "Learn how to configure automatic export settings for your data." + } + ] + } + } + + +7. User Input: "set memo field in export" + Output: + { + "suggestions": { + "actions" : [ + { + "code": "set_memo_field", + "title": "Set/Update memo field for exports", + "description": "Configure the memo field for exported data to include relevant details." + } + ], + "help": [ + { + "code": "memo_field_help", + "title": "How to use memo field in export", + "description": "Learn how to properly set and use the memo field in data exports." + } + ], + "navigations": [ + { + "code": "go_to_advanced_settings", + "title": "Go to Advanced Settings", + "description": "Navigate to the advanced settings section to configure memo field settings." + } + ] + } + } + +8. User Input: "map Fyle field to QBD fields" + Output: + { + "suggestions": { + "actions" : [ + { + "code": "map_fields", + "title": "Map Fyle fields to QBD fields", + "description": "Configure the mapping of one field to another for iif export." + } + ], + "help": [ + { + "code": "map_fields_help", + "title": "How to map fields", + "description": "Learn how to map fields for accurate data handling and export." + } + ], + "navigations": [ + { + "code": "go_to_mappings", + "title": "Go to Mappings Page", + "description": "Navigate to the field mapping section to configure mappings." + } + ] + } + } +""" \ No newline at end of file From 12d9538c933c6a716632cde785f1737002a09385 Mon Sep 17 00:00:00 2001 From: Shreyansh Sahare Date: Tue, 10 Sep 2024 18:33:24 +0530 Subject: [PATCH 06/25] Added api for recent query and get suggestions --- apps/spotlight/prompts/spotlight_prompt.py | 288 +++++++++++---------- apps/spotlight/service.py | 15 +- apps/spotlight/urls.py | 4 + apps/spotlight/views.py | 41 ++- quickbooks_desktop_api/settings.py | 14 +- quickbooks_desktop_api/urls.py | 3 +- requirements.txt | 3 +- 7 files changed, 213 insertions(+), 155 deletions(-) diff --git a/apps/spotlight/prompts/spotlight_prompt.py b/apps/spotlight/prompts/spotlight_prompt.py index 5ca2e3d..5958c9d 100644 --- a/apps/spotlight/prompts/spotlight_prompt.py +++ b/apps/spotlight/prompts/spotlight_prompt.py @@ -12,395 +12,397 @@ 6. IMPORTANT: If the user's search query does not match any specific actions, navigations, or help suggestions, return an empty Array for each key. 6. IMPORTANT: Be very specific regarding the actions you give, only choose actions from the examples given below. 7. Format your response as a JSON object with the following structure: - { + {{ "search": "user's search query", - "suggestions": { + "suggestions": {{ "actions" : [ - { + {{ "code": "unique code for the action", "title": "suggest title" "description": "brief description of the suggestion" - }, + }}, // ... up to two actions ], "navigations": [ - { + {{ "code": "unique code for the navigation", "title": "suggest title" "description": "brief description of the suggestion" - }, + }}, // ... up to two navigations ], "help": [ - { + {{ "code": "unique code for the help", "title": "suggest title" "description": "brief description of the suggestion" - }, + }}, // ... up to two help suggestions ] - } - } + }} + }} "actions" : [ - { + {{ "code": "trigger_export", "title": "Export IIF file", "description": "Export the current data to an IIF file." - }, - { + }}, + {{ "code": "apply_date_filter", "title": "Apply date filter to IIF files", "description": "Filter IIF files by a specified date range for better visibility." - }, - { + }}, + {{ "code": "toggle_export_settings", "title": "Enable/disable export settings", "description": "Toggle the export settings to enable or disable export functionality." - }, - { + }}, + {{ "code": "select_export_module", "title": "Select export module", "description": "Choose the specific module for exporting data." - }, - { + }}, + {{ "code": "set_purchased_from_field", "title": "Set 'Purchased From' field for credit card", "description": "Map the 'Purchased From' field to the credit card account name." - }, - { + }}, + {{ "code": "update_field_mappings", "title": "Update 'Purchased From' field mappings", "description": "Modify the current mapping for the 'Purchased From' field." - }, - { + }}, + {{ "code": "set_automatic_export_settings", "title": "Set/Update automatic export settings", "description": "Configure the automatic export settings for scheduled exports." - }, - { + }}, + {{ "code": "set_memo_field", "title": "Set/Update memo field for exports", "description": "Configure the memo field for exported data to include relevant details." - }, - { + }}, + {{ "code": "map_fields", "title": "Map Fyle fields to QBD fields", "description": "Configure the mapping of one field to another for iif export." - }, - { + }}, + {{ "code": "create_field_mapping", "title": "Create/update new field mapping settings", "description": "Set up a new field mapping for data import/export." - } + }} ] "navigations": [ - { + {{ "code": "go_to_dashboard", "title": "Go to Dashboard", "description": "Navigate to the IIF file management section for import/export options." - }, - { + }}, + {{ "code": "go_to_settings", "title": "Go to Export Settings", "description": "Navigate to the export settings section to manage export configurations." - }, - { + }}, + {{ "code": "go_to_field_mappings", "title": "Go to Field Mappings", "description": "Navigate to the Field Mapping Settings Section to manage Field Mapping Settings." - }, - { + }}, + {{ "code": "go_to_advanced_settings", "title": "Go to Advanced Settings", "description": "Navigate to the advanced settings section to manage automatic export settings." - }, - { + }}, + {{ "code": "go_to_mappings", "title": "Go to Mappings Page", "description": "Navigate to the field mapping section to configure mappings." - } + }} ] "help": [ - { + {{ "code": "learn_export", "title": "Learn more about IIF export", "description": "Get detailed instructions on how to export IIF files." - }, - { + }}, + {{ "code": "date_filter_help", "title": "How to filter IIF files by date", "description": "Learn how to apply date filters when working with IIF files." - }, - { + }}, + {{ "code": "learn_export_settings", "title": "Learn more about export settings", "description": "Understand how to manage and configure export settings." - }, - { + }}, + {{ "code": "configure_credit_card_mapping", "title": "How to configure credit card mapping", "description": "Learn how to set up field mappings for credit card transactions." - }, - { + }}, + {{ "code": "field_mapping_help", "title": "How to create field mappings", "description": "Learn how to create new field mappings for import/export." - }, - { + }}, + {{ "code": "automatic_export_help", "title": "How to set up automatic export", "description": "Learn how to configure automatic export settings for your data." - }, - { + }}, + {{ "code": "memo_field_help", "title": "How to use memo field in export", "description": "Learn how to properly set and use the memo field in data exports." - }, - { + }}, + {{ "code": "map_fields_help", "title": "How to map fields", "description": "Learn how to map fields for accurate data handling and export." - } + }} ] - +--------------------------- +User Query: {user_query} +-------------------------- Examples: 1. User Input Options: ["import and export IIF files", "export"] Output: - { - "suggestions": { + {{ + "suggestions": {{ "actions" : [ - { + {{ "code": "trigger_export", "title": "Export IIF file", "description": "Export the current data to an IIF file." - } + }} ], "navigations": [ - { + {{ "code": "go_to_dashboard", "title": "Go to Dashboard", "description": "Navigate to the IIF file management section for import/export options." - } + }} ], "help": [ - { + {{ "code": "learn_export", "title": "Learn more about IIF export", - "description": "Get detailed instructions on how to export IIF files." - } + "description": "how to export IIF files." + }} ] - } - } + }} + }} 2. User Input Options: ["filter IIF files by date", "date filter", "filter"] Output: - { - "suggestions": { + {{ + "suggestions": {{ "actions" : [ - { + {{ "code": "apply_date_filter", "title": "Apply date filter to IIF files", "description": "Filter IIF files by a specified date range for better visibility." - } + }} ], "help": [ - { + {{ "code": "date_filter_help", "title": "How to filter IIF files by date", "description": "Learn how to apply date filters when working with IIF files." - } + }} ], "navigations": [ - { + {{ "code": "go_to_dashboard", "title": "Go to Dashboard", "description": "Go to the Dashboard where IIF export is listed." - } + }} ] - } - } + }} + }} 3. User Input Options: ["update export settings", "export settings", "Settings"] Output: - { - "suggestions": { + {{ + "suggestions": {{ "actions" : [ - { + {{ "code": "toggle_export_settings", "title": "Enable/disable export settings", "description": "Toggle the export settings to enable or disable export functionality." - }, - { + }}, + {{ "code": "select_export_module", "title": "Select export module", "description": "Choose the specific module for exporting data." - } + }} ], "help": [ - { + {{ "code": "learn_export_settings", "title": "Learn more about export settings", "description": "Understand how to manage and configure export settings." - } + }} ], "navigations": [ - { + {{ "code": "go_to_settings", "title": "Go to Export Settings", "description": "Navigate to the export settings section to manage export configurations." - } + }} ] - } - } + }} + }} 4. User Input: "set purchased from field for credit card" Output: - { - "suggestions": { + {{ + "suggestions": {{ "actions" : [ - { + {{ "code": "set_purchased_from_field", "title": "Set 'Purchased From' field for credit card", "description": "Map the 'Purchased From' field to the credit card account name." - }, - { + }}, + {{ "code": "update_field_mappings", "title": "Update 'Purchased From' field mappings", "description": "Modify the current mapping for the 'Purchased From' field." - } + }} ], "help": [ - { + {{ "code": "configure_credit_card_mapping", "title": "How to configure credit card mapping", "description": "Learn how to set up field mappings for credit card transactions." - } + }} ] "navigations": [ - { + {{ "code": "go_to_settings", "title": "Go to Export Settings", "description": "Navigate to the export settings section to manage export configurations." - } + }} ] - } - } + }} + }} 5. User Input: "create or update field mappings settings" Output: - { - "suggestions": { + {{ + "suggestions": {{ "actions" : [ - { + {{ "code": "create_field_mapping", "title": "Create/update new field mapping settings", "description": "Set up a new field mapping for data import/export." - } + }} ], "navigations": [ - { + {{ "code": "go_to_field_mappings", "title": "Go to Field Mappings", "description": "Navigate to the Field Mapping Settings Section to manage Field Mapping Settings." - } + }} ], "help": [ - { + {{ "code": "field_mapping_help", "title": "How to create field mappings", "description": "Learn how to create new field mappings for import/export." - } + }} ] - } - } + }} + }} 6. User Input: "update automatic export" Output: - { - "suggestions": { + {{ + "suggestions": {{ "actions" : [ - { + {{ "code": "set_automatic_export_settings", "title": "Set/Update automatic export settings", "description": "Configure the automatic export settings for scheduled exports." - } + }} ], "navigations": [ - { + {{ "code": "go_to_advanced_settings", "title": "Go to Advanced Settings", "description": "Navigate to the advanced settings section to manage automatic export settings." - } + }} ], "help": [ - { + {{ "code": "automatic_export_help", "title": "How to set up automatic export", "description": "Learn how to configure automatic export settings for your data." - } + }} ] - } - } + }} + }} 7. User Input: "set memo field in export" Output: - { - "suggestions": { + {{ + "suggestions": {{ "actions" : [ - { + {{ "code": "set_memo_field", "title": "Set/Update memo field for exports", "description": "Configure the memo field for exported data to include relevant details." - } + }} ], "help": [ - { + {{ "code": "memo_field_help", "title": "How to use memo field in export", "description": "Learn how to properly set and use the memo field in data exports." - } + }} ], "navigations": [ - { + {{ "code": "go_to_advanced_settings", "title": "Go to Advanced Settings", "description": "Navigate to the advanced settings section to configure memo field settings." - } + }} ] - } - } + }} + }} 8. User Input: "map Fyle field to QBD fields" Output: - { - "suggestions": { + {{ + "suggestions": {{ "actions" : [ - { + {{ "code": "map_fields", "title": "Map Fyle fields to QBD fields", "description": "Configure the mapping of one field to another for iif export." - } + }} ], "help": [ - { + {{ "code": "map_fields_help", "title": "How to map fields", "description": "Learn how to map fields for accurate data handling and export." - } + }} ], "navigations": [ - { + {{ "code": "go_to_mappings", "title": "Go to Mappings Page", "description": "Navigate to the field mapping section to configure mappings." - } + }} ] - } - } -""" \ No newline at end of file + }} + }} +""" diff --git a/apps/spotlight/service.py b/apps/spotlight/service.py index d3d4d97..a091546 100644 --- a/apps/spotlight/service.py +++ b/apps/spotlight/service.py @@ -1,6 +1,8 @@ -import llm from typing import Dict -from prompts.support_genie import PROMPT as SUPPORT_GENIE_PROMPT +from .prompts.support_genie import PROMPT as SUPPORT_GENIE_PROMPT +from .prompts.spotlight_prompt import PROMPT as SPOTLIGHT_PROMPT + +from . import llm class HelpService: @classmethod @@ -31,3 +33,12 @@ def get_support_response(cls, *, user_query: str) -> str: ) return cls.format_response(response=response) + + +class QueryService: + @classmethod + def get_suggestions(cls, *, user_query: str) -> str: + formatted_prompt = SPOTLIGHT_PROMPT.format( + user_query=user_query + ) + return llm.get_openai_response(system_prompt=formatted_prompt) diff --git a/apps/spotlight/urls.py b/apps/spotlight/urls.py index 9ddefb6..ea8a25f 100644 --- a/apps/spotlight/urls.py +++ b/apps/spotlight/urls.py @@ -14,7 +14,11 @@ """ from django.urls import path +from apps.spotlight.views import QueryView, RecentQueryView + urlpatterns = [ + path('recent_queries/', RecentQueryView.as_view(), name='recent-queries'), + path('query/', QueryView.as_view(), name='query'), ] diff --git a/apps/spotlight/views.py b/apps/spotlight/views.py index 91ea44a..e8b80e0 100644 --- a/apps/spotlight/views.py +++ b/apps/spotlight/views.py @@ -1,3 +1,42 @@ -from django.shortcuts import render +import json +from django.http import JsonResponse +from django.db import transaction +from rest_framework import generics + +from apps.spotlight.models import Query +from apps.spotlight.serializers import QuerySerializer + +from .service import QueryService + # Create your views here. +class RecentQueryView(generics.ListAPIView): + serializer_class = QuerySerializer + # lookup_field = 'workspace_id' + # lookup_url_kwarg = 'workspace_id' + + def get_queryset(self): + filters = { + 'workspace_id': self.kwargs.get('workspace_id'), + 'user': self.request.user, + } + + return Query.objects.filter( + # **filters + ).all().order_by("-created_at")[:5] + + +class QueryView(generics.CreateAPIView): + def post(self, request, *args, **kwargs): + with transaction.atomic(): + payload = json.loads(request.body) + user_query = payload["query"] + suggestions = QueryService.get_suggestions(user_query=user_query) + + # Query.objects.create( + # query=user_query, + # workspace_id=1, + # _llm_response=suggestions, + # user=request.user + # ) + return JsonResponse(data=suggestions["suggestions"]) diff --git a/quickbooks_desktop_api/settings.py b/quickbooks_desktop_api/settings.py index b6907c9..61f634f 100644 --- a/quickbooks_desktop_api/settings.py +++ b/quickbooks_desktop_api/settings.py @@ -106,13 +106,13 @@ } REST_FRAMEWORK = { - 'DEFAULT_PERMISSION_CLASSES': ( - 'rest_framework.permissions.IsAuthenticated', - 'apps.workspaces.permissions.WorkspacePermissions' - ), - 'DEFAULT_AUTHENTICATION_CLASSES': ( - 'fyle_rest_auth.authentication.FyleJWTAuthentication', - ), + # 'DEFAULT_PERMISSION_CLASSES': ( + # 'rest_framework.permissions.IsAuthenticated', + # 'apps.workspaces.permissions.WorkspacePermissions' + # ), + # 'DEFAULT_AUTHENTICATION_CLASSES': ( + # 'fyle_rest_auth.authentication.FyleJWTAuthentication', + # ), 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination', 'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'], 'PAGE_SIZE': 100 diff --git a/quickbooks_desktop_api/urls.py b/quickbooks_desktop_api/urls.py index 04da47d..f385821 100644 --- a/quickbooks_desktop_api/urls.py +++ b/quickbooks_desktop_api/urls.py @@ -18,5 +18,6 @@ urlpatterns = [ path('api/auth/', include('fyle_rest_auth.urls')), path('api/workspaces/', include('apps.workspaces.urls')), - path('api/user/', include('apps.users.urls')) + path('api/user/', include('apps.users.urls')), + path('api/spotlight/', include('apps.spotlight.urls')) ] diff --git a/requirements.txt b/requirements.txt index 0ade997..e2a8ca4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,6 @@ -# boto client for using bedrock +# LLM Clients boto3==1.35.14 +openai==1.44.0 # Croniter package for djangoq croniter==1.3.8 From b7c9eb4ace575dbed919bb8591c7fd9fe7be7067 Mon Sep 17 00:00:00 2001 From: Shreyansh Sahare Date: Tue, 10 Sep 2024 18:33:36 +0530 Subject: [PATCH 07/25] Added api for recent query and get suggestions --- apps/spotlight/serializers.py | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 apps/spotlight/serializers.py diff --git a/apps/spotlight/serializers.py b/apps/spotlight/serializers.py new file mode 100644 index 0000000..59cb025 --- /dev/null +++ b/apps/spotlight/serializers.py @@ -0,0 +1,9 @@ +from rest_framework import serializers + +from .models import Query + + +class QuerySerializer(serializers.ModelSerializer): + class Meta: + model = Query + fields = ['query'] From 8a7a375403e94270e0b09735d1eecd7185e845cb Mon Sep 17 00:00:00 2001 From: Shreyansh Sahare Date: Tue, 10 Sep 2024 23:03:16 +0530 Subject: [PATCH 08/25] added api for recent queries and api to call get suggestions --- apps/spotlight/views.py | 51 ++++++++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/apps/spotlight/views.py b/apps/spotlight/views.py index e8b80e0..53111a2 100644 --- a/apps/spotlight/views.py +++ b/apps/spotlight/views.py @@ -10,21 +10,50 @@ # Create your views here. +# class RecentQueryView(generics.ListAPIView): +# serializer_class = QuerySerializer +# # lookup_field = 'workspace_id' +# # lookup_url_kwarg = 'workspace_id' + +# def get_queryset(self): +# filters = { +# # 'workspace_id': self.kwargs.get('workspace_id'), +# # 'user': self.request.user, +# 'workspace_id': 1, +# 'user_id': 1, +# } + +# return Query.objects.filter( +# **filters +# ).all().order_by("-created_at")[:5] + + class RecentQueryView(generics.ListAPIView): serializer_class = QuerySerializer # lookup_field = 'workspace_id' # lookup_url_kwarg = 'workspace_id' - def get_queryset(self): + def get(self, request, *args, **kwargs): filters = { - 'workspace_id': self.kwargs.get('workspace_id'), - 'user': self.request.user, + # 'workspace_id': self.kwargs.get('workspace_id'), + # 'user': self.request.user, + 'workspace_id': 1, + 'user_id': 1, } - return Query.objects.filter( - # **filters + _recent_queries = Query.objects.filter( + **filters ).all().order_by("-created_at")[:5] + # recent_queries = [] + # for query in _recent_queries: + # recent_queries.append({ + # "query": query.query, + # "suggestions": query._llm_response["suggestions"] + # }) + recent_queries = [query.query for query in _recent_queries] + return JsonResponse(data={"recent_queries": recent_queries}, safe=False) + class QueryView(generics.CreateAPIView): def post(self, request, *args, **kwargs): @@ -33,10 +62,10 @@ def post(self, request, *args, **kwargs): user_query = payload["query"] suggestions = QueryService.get_suggestions(user_query=user_query) - # Query.objects.create( - # query=user_query, - # workspace_id=1, - # _llm_response=suggestions, - # user=request.user - # ) + Query.objects.create( + query=user_query, + workspace_id=1, + _llm_response=suggestions, + user_id=1 + ) return JsonResponse(data=suggestions["suggestions"]) From 6df4b548dbb826d14e244a30a66388efa4abc097 Mon Sep 17 00:00:00 2001 From: Shreyansh Sahare Date: Tue, 10 Sep 2024 23:11:29 +0530 Subject: [PATCH 09/25] api for help details --- apps/spotlight/urls.py | 3 ++- apps/spotlight/views.py | 10 +++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/apps/spotlight/urls.py b/apps/spotlight/urls.py index ea8a25f..508aba7 100644 --- a/apps/spotlight/urls.py +++ b/apps/spotlight/urls.py @@ -14,11 +14,12 @@ """ from django.urls import path -from apps.spotlight.views import QueryView, RecentQueryView +from apps.spotlight.views import HelpQueryView, QueryView, RecentQueryView urlpatterns = [ path('recent_queries/', RecentQueryView.as_view(), name='recent-queries'), path('query/', QueryView.as_view(), name='query'), + path('help/', HelpQueryView.as_view(), name='help'), ] diff --git a/apps/spotlight/views.py b/apps/spotlight/views.py index 53111a2..312aeaa 100644 --- a/apps/spotlight/views.py +++ b/apps/spotlight/views.py @@ -6,7 +6,7 @@ from apps.spotlight.models import Query from apps.spotlight.serializers import QuerySerializer -from .service import QueryService +from .service import HelpService, QueryService # Create your views here. @@ -69,3 +69,11 @@ def post(self, request, *args, **kwargs): user_id=1 ) return JsonResponse(data=suggestions["suggestions"]) + + +class HelpQueryView(generics.CreateAPIView): + def post(self, request, *args, **kwargs): + payload = json.loads(request.body) + user_query = payload["query"] + support_response = HelpService.get_support_response(user_query=user_query) + return JsonResponse(data={"message": support_response}) From 4d528cb1b684e778aea9a5c2b124215489a13fe8 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Wed, 11 Sep 2024 23:15:48 +0530 Subject: [PATCH 10/25] fixed prompt and api --- apps/spotlight/llm.py | 12 +- apps/spotlight/prompts/spotlight_prompt.py | 634 ++++++++++++--------- apps/spotlight/views.py | 17 +- apps/workspaces/urls.py | 1 + quickbooks_desktop_api/settings.py | 14 +- quickbooks_desktop_api/urls.py | 3 +- 6 files changed, 392 insertions(+), 289 deletions(-) diff --git a/apps/spotlight/llm.py b/apps/spotlight/llm.py index 6cfb327..7db23e5 100644 --- a/apps/spotlight/llm.py +++ b/apps/spotlight/llm.py @@ -5,12 +5,12 @@ from typing import Dict -AWS_REGION = os.environ["AWS_REGION"] -AWS_ACCESS_KEY_ID = os.environ["AWS_ACCESS_KEY_ID"] -AWS_SECRET_ACCESS_KEY = os.environ["AWS_SECRET_ACCESS_KEY"] +AWS_REGION = os.environ.get("AWS_REGION") +AWS_ACCESS_KEY_ID = os.environ.get("AWS_ACCESS_KEY_ID") +AWS_SECRET_ACCESS_KEY = os.environ.get("AWS_SECRET_ACCESS_KEY") -OPENAI_API_KEY = os.environ["OPENAI_API_KEY"] -KNOWLEDGE_BASE_ID = os.environ["KNOWLEDGE_BASE_ID"] +OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY") +KNOWLEDGE_BASE_ID = os.environ.get("KNOWLEDGE_BASE_ID") bedrock_session = boto3.Session( @@ -37,7 +37,7 @@ def get_openai_response(*, system_prompt: str) -> dict: {"role": "system", "content": system_prompt} ], temperature=0, - max_tokens=256, + max_tokens=1000, top_p=0, frequency_penalty=0, presence_penalty=0 diff --git a/apps/spotlight/prompts/spotlight_prompt.py b/apps/spotlight/prompts/spotlight_prompt.py index 5958c9d..3c00bd6 100644 --- a/apps/spotlight/prompts/spotlight_prompt.py +++ b/apps/spotlight/prompts/spotlight_prompt.py @@ -1,17 +1,19 @@ PROMPT = """ You are an AI assistant for integrations usage in expense management application. Your role is to interpret user searches and provide relevant suggestions in a JSON format. Use the following guidelines: -1. Analyze the user's search query to determine the context and intent. -2. Based on the search, provide up to four relevant suggestions that may include: - - Action: Suggest a task the user can perform - - Navigation: Navigate user to a page related to user's query - - Help: Offer guidance or explanations -3. Choose Action, Navigation and Help suggestions from the map given below for each. -4. Ensure that the suggestions are relevant to the user's search query and provide actionable or informative options. -5. If a query is ambiguous, prioritize the most likely interpretations. -6. IMPORTANT: If the user's search query does not match any specific actions, navigations, or help suggestions, return an empty Array for each key. -6. IMPORTANT: Be very specific regarding the actions you give, only choose actions from the examples given below. -7. Format your response as a JSON object with the following structure: +-------------------- + +General Intructions: + 1. Analyze the user's search query to determine the context and intent. + 2. Based on the search, provide up to four relevant suggestions that may include: + - Action: Suggest a task the user can perform + - Navigation: Navigate user to a page related to user's query + - Help: Offer guidance or explanations + 4. Ensure that the suggestions are relevant to the user's search query and provide actionable or informative options. + 5. If a query is ambiguous, prioritize the most likely interpretations. + 6. IMPORTANT: If the user's search query does not match any specific actions, navigations, or help suggestions, return an empty Array for each key. + 7. IMPORTANT: Be very specific regarding the actions you give, only choose actions from the examples given below. + 8. Format your response as a JSON object with the following structure: {{ "search": "user's search query", "suggestions": {{ @@ -27,301 +29,398 @@ {{ "code": "unique code for the navigation", "title": "suggest title" - "description": "brief description of the suggestion" + "description": "brief description of the suggestion", + "url": "URL to navigate to" }}, // ... up to two navigations ], "help": [ - {{ - "code": "unique code for the help", + {{, "title": "suggest title" - "description": "brief description of the suggestion" + "description": "form a question based on user question" }}, // ... up to two help suggestions ] }} }} -"actions" : [ - {{ - "code": "trigger_export", - "title": "Export IIF file", - "description": "Export the current data to an IIF file." - }}, - {{ - "code": "apply_date_filter", - "title": "Apply date filter to IIF files", - "description": "Filter IIF files by a specified date range for better visibility." - }}, - {{ - "code": "toggle_export_settings", - "title": "Enable/disable export settings", - "description": "Toggle the export settings to enable or disable export functionality." - }}, - {{ - "code": "select_export_module", - "title": "Select export module", - "description": "Choose the specific module for exporting data." - }}, - {{ - "code": "set_purchased_from_field", - "title": "Set 'Purchased From' field for credit card", - "description": "Map the 'Purchased From' field to the credit card account name." - }}, - {{ - "code": "update_field_mappings", - "title": "Update 'Purchased From' field mappings", - "description": "Modify the current mapping for the 'Purchased From' field." - }}, - {{ - "code": "set_automatic_export_settings", - "title": "Set/Update automatic export settings", - "description": "Configure the automatic export settings for scheduled exports." - }}, - {{ - "code": "set_memo_field", - "title": "Set/Update memo field for exports", - "description": "Configure the memo field for exported data to include relevant details." - }}, - {{ - "code": "map_fields", - "title": "Map Fyle fields to QBD fields", - "description": "Configure the mapping of one field to another for iif export." - }}, - {{ - "code": "create_field_mapping", - "title": "Create/update new field mapping settings", - "description": "Set up a new field mapping for data import/export." - }} -] +-------------------- + +Actions Intructions: + 1. Provide specific actions that the user can take based on their search query. + 2. Each action should have a unique code, title, and a brief description. + 3. The action should be actionable and relevant to the user's search query. + 4. IMPORTANT: Only choose actions from the examples given below. + 5. Interpret the user's search query to suggest relevant actions. + 6. Ignore spelling errors and variations in the user's search query. + 7. Suggest the best action that matches the user's search query. -"navigations": [ - {{ - "code": "go_to_dashboard", - "title": "Go to Dashboard", - "description": "Navigate to the IIF file management section for import/export options." - }}, - {{ - "code": "go_to_settings", - "title": "Go to Export Settings", - "description": "Navigate to the export settings section to manage export configurations." - }}, - {{ - "code": "go_to_field_mappings", - "title": "Go to Field Mappings", - "description": "Navigate to the Field Mapping Settings Section to manage Field Mapping Settings." - }}, - {{ - "code": "go_to_advanced_settings", - "title": "Go to Advanced Settings", - "description": "Navigate to the advanced settings section to manage automatic export settings." - }}, - {{ - "code": "go_to_mappings", - "title": "Go to Mappings Page", - "description": "Navigate to the field mapping section to configure mappings." - }} -] + Actions Map: + "actions" : [ + {{ + "code": "trigger_export", + "title": "Export IIF file", + "description": "Export the current data to an IIF file." + }}, + {{ + "code": "enable_reimbursable_expenses_export", + "title": "Enable reimbursable export settings", + "description": "Enable the option to export reimbursable expenses in Export Configuration." + }}, + {{ + "code": "disable_reimbursable_expenses_export", + "title": "Disable reimbursable export settings", + "description": "Disable the option to export reimbursable expenses in Export Configuration." + }}, + {{ + "code": "set_reimbursable_expenses_export_module_bill", + "title": "Select reimbursable export module as bill", + "description": "Choose Bill as the type of transaction in QuickBooks Desktop to export your Fyle expenses." + }}, + {{ + "code": "set_reimbursable_expenses_export_module_journal_entry", + "title": "Select reimbursable export module as journal entry", + "description": "Choose Journal Entry as the type of transaction in QuickBooks Desktop to export your Fyle expenses." + }}, + {{ + "code": "set_reimbursable_expenses_export_grouping_expense" + "title": "Group reimbursable expenses export by expense", + "description": "Set grouping to expense, this grouping reflects how the expense entries are posted in QuickBooks Desktop." + }}, + {{ + "code": "set_reimbursable_expenses_export_grouping_expense_report", + "title": "Group reimbursable expenses export by expense report", + "description": "Set grouping to expense_report, this grouping reflects how the expense entries are posted in QuickBooks Desktop." + }}, + {{ + "code": "set_reimbursable_expenses_export_state_processing", + "title": "Set reimbursable expenses export state as processing", + "description": "You could choose to export expenses when they have been approved and are awaiting payment clearance." + }}, + {{ + "code": "set_reimbursable_expenses_export_state_paid", + "title": "Set reimbursable expenses export state as paid", + "description": "You could choose to export expenses when they have been paid out." + }}, + {{ + "code": "enable_corporate_card_expenses_export", + "title": "Enable option corporate card expenses export", + "description": "Enable the option to export of credit card expenses from Fyle to QuickBooks Desktop." + }}, + {{ + "code": "disable_corporate_card_expenses_export", + "title": "Disable reimbursable export settings", + "description": "Disable the option to export of credit card expenses from Fyle to QuickBooks Desktop." + }}, + {{ + "code": "set_corporate_credit_card_expenses_export_credit_card_purchase", + "title": "Set Credit Card Purchase transaction type to export", + "description": "Credit Card Purchase type of transaction in QuickBooks Desktop to be export as Fyle expenses." + }}, + {{ + "code": "set_corporate_credit_card_expenses_export_journal_entry", + "title": "Set Journal Entry transaction type to export", + "description": "Journal Entry type of transaction in QuickBooks Desktop to be export as Fyle expenses." + }}, + {{ + "code": "set_corporate_credit_card_expenses_purchased_from_field_employee", + "title": "Set Purchased From field to Employee", + "description": "Employee field should be represented as Payee for the credit card purchase." + }}, + {{ + "code": "set_corporate_credit_card_expenses_purchased_from_field_vendor", + "title": "Set Purchased From field to Vendor", + "description": "Vendor field should be represented as Payee for the credit card purchase." + }}, + {{ + "code": "set_corporate_credit_card_expenses_export_grouping_report", + "title": "Group corporate credit expenses export to report", + "description": "Group reports as the expense entries posted in QuickBooks Desktop." + }}, + {{ + "code": "set_corporate_credit_card_expenses_export_grouping_expense", + "title": "Group corporate credit expenses export to expenses", + "description": "Group expense as the expense entries posted in QuickBooks Desktop." + }}, + {{ + "code": "set_corporate_credit_card_expenses_export_state_approved", + "title": "Set corporate credit expenses export to approved state", + "description": "Set corporate credit expenses to export expenses when they have been approved and are awaiting payment clearance" + }}, + {{ + "code": "set_corporate_credit_card_expenses_export_state_closed", + "title": "Set corporate credit expenses export to closed state", + "description": "Set corporate credit expenses to export expenses when they have been closed" + }}, + {{ + "code": "set_customer_field_mapping_to_project" + "title": "Map Customer field to Project", + "description": "Set Project field in Fyle mapped to 'Customers' field in QuickBooks Desktops." + }}, + {{ + "code": "set_customer_field_mapping_to_cost_center", + "title": "Map Customer field to Cost Center", + "description": "Set Cost Center field in Fyle mapped to 'Customers' field in QuickBooks Desktop." + }}, + {{ + "code" "set_class_field_mapping_to_project", + "title": "Map Class field to Project", + "description": "Set Project field in Fyle mapped to 'Class' field in QuickBooks Desktop." + }}, + {{ + "code": "set_class_field_mapping_to_cost_center", + "title": "Map Class field to Cost Center", + "description": "Set Cost Center field in Fyle mapped to 'Class' field in QuickBooks Desktop." + }} + ] + +-------------------- + +Navigations Intructions: + 1. Provide specific navigations that the user can take based on their search query. + 2. Each navigation should have a unique code, title, description, and a URL. + 3. The navigation should guide the user to a relevant page based on their search query. + 4. IMPORTANT: Only choose navigations from the examples given below. + 5. Interpret the user's search query to suggest relevant navigations. + 6. Ignore spelling errors and variations in the user's search query. + 7. Suggest the best navigation that matches the user's search query. + + Navigations Map: + "navigations": [ + {{ + "code": "go_to_dashboard", + "title": "Go to Dashboard", + "description": "Navigate to the IIF file management section for import/export options.", + "url": "https://example.com/dashboard" + }}, + {{ + "code": "go_to_settings", + "title": "Go to Export Settings", + "description": "Navigate to the export settings section to manage export configurations.", + "url": "https://example.com/settings" + }}, + {{ + "code": "go_to_field_mappings", + "title": "Go to Field Mappings", + "description": "Navigate to the Field Mapping Settings Section to manage Field Mapping Settings.", + "url": "https://example.com/field_mappings" + }}, + {{ + "code": "go_to_advanced_settings", + "title": "Go to Advanced Settings", + "description": "Navigate to the advanced settings section to manage automatic export settings.", + "url": "https://example.com/advanced_settings" + }}, + {{ + "code": "go_to_mappings", + "title": "Go to Mappings Page", + "description": "Navigate to the field mapping section to configure mappings.", + "url": "https://example.com/mappings" + }} + ] + +-------------------- + +Help Intructions: + 1. Provide specific help suggestions based on the user's search query. + 2. Each help suggestion should have a unique code, title, and a brief description. + 3. The help suggestion should offer guidance or explanations related to the user's search query. + 4. IMPORTANT: Only choose help suggestions from the examples given below. + 5. Interpret the user's search query to suggest relevant help options. + 6. Ignore spelling errors and variations in the user's search query. + 7. Suggest the best help that matches the user's search query. + + Help Map: + "help": [ + {{ + "code": "learn_export", + "title": "Learn more about IIF export", + "description": "How to export IIF File?." + }}, + {{ + "code": "date_filter_help", + "title": "How to filter IIF files by date", + "description": "How to filter by date in QBD?" + }}, + {{ + "code": "learn_export_settings", + "title": "Learn more about export settings", + "description": "how to manage and configure export settings." + }}, + {{ + "code": "configure_credit_card_mapping", + "title": "How to configure credit card mapping", + "description": "how to set up field mappings for credit card transactions." + }}, + {{ + "code": "field_mapping_help", + "title": "How to create field mappings", + "description": "how to create new field mappings for import/export." + }}, + {{ + "code": "automatic_export_help", + "title": "How to set up automatic export", + "description": "how to configure automatic export settings for your data." + }}, + {{ + "code": "memo_field_help", + "title": "How to use memo field in export", + "description": "how to properly set and use the memo field in data exports." + }}, + {{ + "code": "map_fields_help", + "title": "How to map fields", + "description": "how to map fields for accurate data handling and export." + }} + ] -"help": [ - {{ - "code": "learn_export", - "title": "Learn more about IIF export", - "description": "Get detailed instructions on how to export IIF files." - }}, - {{ - "code": "date_filter_help", - "title": "How to filter IIF files by date", - "description": "Learn how to apply date filters when working with IIF files." - }}, - {{ - "code": "learn_export_settings", - "title": "Learn more about export settings", - "description": "Understand how to manage and configure export settings." - }}, - {{ - "code": "configure_credit_card_mapping", - "title": "How to configure credit card mapping", - "description": "Learn how to set up field mappings for credit card transactions." - }}, - {{ - "code": "field_mapping_help", - "title": "How to create field mappings", - "description": "Learn how to create new field mappings for import/export." - }}, - {{ - "code": "automatic_export_help", - "title": "How to set up automatic export", - "description": "Learn how to configure automatic export settings for your data." - }}, - {{ - "code": "memo_field_help", - "title": "How to use memo field in export", - "description": "Learn how to properly set and use the memo field in data exports." - }}, - {{ - "code": "map_fields_help", - "title": "How to map fields", - "description": "Learn how to map fields for accurate data handling and export." - }} -] --------------------------- User Query: {user_query} --------------------------- +--------------------------- Examples: -1. User Input Options: ["import and export IIF files", "export"] +1. User Input Options: ["import and export IIF files", "export", "IIF export", "trigger export", "export current data", "export to IIF", "go to dashboard", "dashboard", "manage IIF files", "import IIF files", "learn about IIF export", "learn export", "IIF file management"] + Output: {{ - "suggestions": {{ - "actions" : [ - {{ - "code": "trigger_export", - "title": "Export IIF file", - "description": "Export the current data to an IIF file." - }} + "suggestions": {{ + "actions": [ + {{ + "code": "trigger_export", + "title": "Export IIF file", + "description": "Export the current data to an IIF file." + }} ], "navigations": [ - {{ - "code": "go_to_dashboard", - "title": "Go to Dashboard", - "description": "Navigate to the IIF file management section for import/export options." - }} + {{ + "code": "go_to_dashboard", + "title": "Go to Dashboard", + "url": "https://example.com/dashboard", + "description": "Navigate to the IIF file management section for import/export options." + }} ], "help": [ - {{ - "code": "learn_export", - "title": "Learn more about IIF export", - "description": "how to export IIF files." - }} - ] - }} - }} - -2. User Input Options: ["filter IIF files by date", "date filter", "filter"] - Output: - {{ - "suggestions": {{ - "actions" : [ - {{ - "code": "apply_date_filter", - "title": "Apply date filter to IIF files", - "description": "Filter IIF files by a specified date range for better visibility." - }} - ], - "help": [ - {{ - "code": "date_filter_help", - "title": "How to filter IIF files by date", - "description": "Learn how to apply date filters when working with IIF files." - }} - ], - "navigations": [ - {{ - "code": "go_to_dashboard", - "title": "Go to Dashboard", - "description": "Go to the Dashboard where IIF export is listed." - }} + {{ + "code": "learn_export", + "title": "Learn more about IIF export", + "description": "How to export IIF files?" + }} ] }} }} -3. User Input Options: ["update export settings", "export settings", "Settings"] +2. User Input Options: ["update export settings", "export settings", "Settings", "enable reimbursable export", "disable reimbursable export", "select export module", "group by expense", "group by expense report", "export state as processing", "export state as paid", "select module as bill", "select module as journal entry", "learn about export settings", "go to export settings", "enable", "disable", "export", "grouping", "processing state", "paid state", "reimbursable export", "configure export"] + Output: {{ - "suggestions": {{ - "actions" : [ - {{ - "code": "toggle_export_settings", - "title": "Enable/disable export settings", - "description": "Toggle the export settings to enable or disable export functionality." - }}, - {{ - "code": "select_export_module", - "title": "Select export module", - "description": "Choose the specific module for exporting data." - }} + "suggestions": {{ + "actions": [ + {{ + "code": "enable_reimbursable_expenses_export", + "title": "Enable reimbursable export settings", + "description": "Enable the option to export reimbursable expenses in Export Configuration." + }}, + {{ + "code": "disable_reimbursable_expenses_export", + "title": "Disable reimbursable export settings", + "description": "Disable the option to export reimbursable expenses in Export Configuration." + }}, + {{ + "code": "set_reimbursable_expenses_export_module_bill", + "title": "Select reimbursable export module as bill", + "description": "Choose Bill as the type of transaction in QuickBooks Desktop to export your Fyle expenses." + }}, + {{ + "code": "set_reimbursable_expenses_export_module_journal_entry", + "title": "Select reimbursable export module as journal entry", + "description": "Choose Journal Entry as the type of transaction in QuickBooks Desktop to export your Fyle expenses." + }}, + {{ + "code": "set_reimbursable_expenses_export_grouping_expense", + "title": "Group reimbursable expenses export by expense", + "description": "Set grouping to expense, this grouping reflects how the expense entries are posted in QuickBooks Desktop." + }}, + {{ + "code": "set_reimbursable_expenses_export_grouping_expense_report", + "title": "Group reimbursable expenses export by expense report", + "description": "Set grouping to expense_report, this grouping reflects how the expense entries are posted in QuickBooks Desktop." + }}, + {{ + "code": "set_reimbursable_expenses_export_export_state_processing", + "title": "Set reimbursable expenses export state as processing", + "description": "You could choose to export expenses when they have been approved and are awaiting payment clearance." + }}, + {{ + "code": "set_reimbursable_expenses_export_export_state_paid", + "title": "Set reimbursable expenses export state as paid", + "description": "You could choose to export expenses when they have been paid out." + }} ], "help": [ - {{ - "code": "learn_export_settings", - "title": "Learn more about export settings", - "description": "Understand how to manage and configure export settings." - }} + {{ + "code": "learn_export_settings", + "title": "Learn more about export settings", + "description": "How to manage and configure export settings?" + }} ], "navigations": [ - {{ - "code": "go_to_settings", - "title": "Go to Export Settings", - "description": "Navigate to the export settings section to manage export configurations." - }} + {{ + "code": "go_to_settings", + "title": "Go to Export Settings", + "description": "Navigate to the export settings section to manage export configurations.", + "url": "https://example.com/settings" + }} ] }} }} -4. User Input: "set purchased from field for credit card" - Output: - {{ - "suggestions": {{ - "actions" : [ - {{ - "code": "set_purchased_from_field", - "title": "Set 'Purchased From' field for credit card", - "description": "Map the 'Purchased From' field to the credit card account name." - }}, - {{ - "code": "update_field_mappings", - "title": "Update 'Purchased From' field mappings", - "description": "Modify the current mapping for the 'Purchased From' field." - }} - ], - "help": [ - {{ - "code": "configure_credit_card_mapping", - "title": "How to configure credit card mapping", - "description": "Learn how to set up field mappings for credit card transactions." - }} - ] - "navigations": [ - {{ - "code": "go_to_settings", - "title": "Go to Export Settings", - "description": "Navigate to the export settings section to manage export configurations." - }} - ] - }} - }} +3. User Input: ["create or update field mappings settings", "update field mappings", "create field mappings", "field mappings", "map customer field to project", "map customer field to cost center", "map class field to project", "map class field to cost center", "field mapping settings", "go to field mappings", "learn field mappings", "field mapping help", "create new field mapping", "update field mapping", "import field mappings", "export field mappings"] -5. User Input: "create or update field mappings settings" Output: {{ - "suggestions": {{ - "actions" : [ - {{ - "code": "create_field_mapping", - "title": "Create/update new field mapping settings", - "description": "Set up a new field mapping for data import/export." - }} + "suggestions": {{ + "actions": [ + {{ + "code": "set_customer_field_mapping_to_project", + "title": "Map Customer field to Project", + "description": "Set Project field in Fyle mapped to 'Customers' field in QuickBooks Desktop." + }}, + {{ + "code": "set_customer_field_mapping_to_cost_center", + "title": "Map Customer field to Cost Center", + "description": "Set Cost Center field in Fyle mapped to 'Customers' field in QuickBooks Desktop." + }}, + {{ + "code": "set_class_field_mapping_to_project", + "title": "Map Class field to Project", + "description": "Set Project field in Fyle mapped to 'Class' field in QuickBooks Desktop." + }}, + {{ + "code": "set_class_field_mapping_to_cost_center", + "title": "Map Class field to Cost Center", + "description": "Set Cost Center field in Fyle mapped to 'Class' field in QuickBooks Desktop." + }} ], "navigations": [ - {{ - "code": "go_to_field_mappings", - "title": "Go to Field Mappings", - "description": "Navigate to the Field Mapping Settings Section to manage Field Mapping Settings." - }} + {{ + "code": "go_to_field_mappings", + "title": "Go to Field Mappings", + "description": "Navigate to the Field Mapping Settings Section to manage Field Mapping Settings.", + "url": "https://example.com/field_mappings" + }} ], "help": [ - {{ - "code": "field_mapping_help", - "title": "How to create field mappings", - "description": "Learn how to create new field mappings for import/export." - }} + {{ + "code": "field_mapping_help", + "title": "How to create field mappings", + "description": "How to create new field mappings for import/export." + }} ] }} }} -6. User Input: "update automatic export" +4. User Input: "update automatic export" Output: {{ "suggestions": {{ @@ -336,21 +435,22 @@ {{ "code": "go_to_advanced_settings", "title": "Go to Advanced Settings", - "description": "Navigate to the advanced settings section to manage automatic export settings." + "description": "Navigate to the advanced settings section to manage automatic export settings.", + "url": "https://example.com/advanced_settings }} ], "help": [ {{ "code": "automatic_export_help", "title": "How to set up automatic export", - "description": "Learn how to configure automatic export settings for your data." + "description": "how to configure automatic export settings for your data?" }} ] }} }} -7. User Input: "set memo field in export" +5. User Input: "set memo field in export" Output: {{ "suggestions": {{ @@ -365,20 +465,21 @@ {{ "code": "memo_field_help", "title": "How to use memo field in export", - "description": "Learn how to properly set and use the memo field in data exports." + "description": "how to properly set and use the memo field in data exports?" }} ], "navigations": [ {{ "code": "go_to_advanced_settings", "title": "Go to Advanced Settings", - "description": "Navigate to the advanced settings section to configure memo field settings." + "description": "Navigate to the advanced settings section to configure memo field settings.", + "url": "https://example.com/advanced_settings" }} ] }} }} -8. User Input: "map Fyle field to QBD fields" +6. User Input: "map Fyle field to QBD fields" Output: {{ "suggestions": {{ @@ -393,16 +494,17 @@ {{ "code": "map_fields_help", "title": "How to map fields", - "description": "Learn how to map fields for accurate data handling and export." + "description": "how to map fields for accurate data handling and export?" }} ], "navigations": [ {{ "code": "go_to_mappings", "title": "Go to Mappings Page", - "description": "Navigate to the field mapping section to configure mappings." + "description": "Navigate to the field mapping section to configure mappings.", + url: "https://example.com/mappings" }} ] }} }} -""" +""" \ No newline at end of file diff --git a/apps/spotlight/views.py b/apps/spotlight/views.py index 312aeaa..54f5ae4 100644 --- a/apps/spotlight/views.py +++ b/apps/spotlight/views.py @@ -30,15 +30,13 @@ class RecentQueryView(generics.ListAPIView): serializer_class = QuerySerializer - # lookup_field = 'workspace_id' - # lookup_url_kwarg = 'workspace_id' + lookup_field = 'workspace_id' + lookup_url_kwarg = 'workspace_id' def get(self, request, *args, **kwargs): filters = { - # 'workspace_id': self.kwargs.get('workspace_id'), - # 'user': self.request.user, - 'workspace_id': 1, - 'user_id': 1, + 'workspace_id': self.kwargs.get('workspace_id'), + 'user': self.request.user, } _recent_queries = Query.objects.filter( @@ -57,16 +55,19 @@ def get(self, request, *args, **kwargs): class QueryView(generics.CreateAPIView): def post(self, request, *args, **kwargs): + workspace_id = self.kwargs.get('workspace_id') + user = self.request.user with transaction.atomic(): payload = json.loads(request.body) user_query = payload["query"] suggestions = QueryService.get_suggestions(user_query=user_query) + print("suggestions", suggestions) Query.objects.create( query=user_query, - workspace_id=1, + workspace_id=workspace_id, _llm_response=suggestions, - user_id=1 + user_id=user.id ) return JsonResponse(data=suggestions["suggestions"]) diff --git a/apps/workspaces/urls.py b/apps/workspaces/urls.py index 7b88a3e..8c7e3d1 100644 --- a/apps/workspaces/urls.py +++ b/apps/workspaces/urls.py @@ -34,4 +34,5 @@ path('/accounting_exports/', include('apps.tasks.urls')), path('/qbd_mappings/', include('apps.mappings.urls')), path('/fyle/', include('apps.fyle.urls')), + path('/spotlight/', include('apps.spotlight.urls')) ] diff --git a/quickbooks_desktop_api/settings.py b/quickbooks_desktop_api/settings.py index 61f634f..b6907c9 100644 --- a/quickbooks_desktop_api/settings.py +++ b/quickbooks_desktop_api/settings.py @@ -106,13 +106,13 @@ } REST_FRAMEWORK = { - # 'DEFAULT_PERMISSION_CLASSES': ( - # 'rest_framework.permissions.IsAuthenticated', - # 'apps.workspaces.permissions.WorkspacePermissions' - # ), - # 'DEFAULT_AUTHENTICATION_CLASSES': ( - # 'fyle_rest_auth.authentication.FyleJWTAuthentication', - # ), + 'DEFAULT_PERMISSION_CLASSES': ( + 'rest_framework.permissions.IsAuthenticated', + 'apps.workspaces.permissions.WorkspacePermissions' + ), + 'DEFAULT_AUTHENTICATION_CLASSES': ( + 'fyle_rest_auth.authentication.FyleJWTAuthentication', + ), 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination', 'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'], 'PAGE_SIZE': 100 diff --git a/quickbooks_desktop_api/urls.py b/quickbooks_desktop_api/urls.py index f385821..04da47d 100644 --- a/quickbooks_desktop_api/urls.py +++ b/quickbooks_desktop_api/urls.py @@ -18,6 +18,5 @@ urlpatterns = [ path('api/auth/', include('fyle_rest_auth.urls')), path('api/workspaces/', include('apps.workspaces.urls')), - path('api/user/', include('apps.users.urls')), - path('api/spotlight/', include('apps.spotlight.urls')) + path('api/user/', include('apps.users.urls')) ] From 7ff81094b0abd1bab621110af91f0468989f18cd Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Thu, 12 Sep 2024 11:28:50 +0530 Subject: [PATCH 11/25] Actions api --- apps/spotlight/urls.py | 3 ++- apps/spotlight/views.py | 31 ++++++++++++++++++++++++++++++- apps/workspaces/tasks.py | 8 ++++++++ apps/workspaces/views.py | 7 ++----- 4 files changed, 42 insertions(+), 7 deletions(-) diff --git a/apps/spotlight/urls.py b/apps/spotlight/urls.py index 508aba7..ff11aa1 100644 --- a/apps/spotlight/urls.py +++ b/apps/spotlight/urls.py @@ -14,7 +14,7 @@ """ from django.urls import path -from apps.spotlight.views import HelpQueryView, QueryView, RecentQueryView +from apps.spotlight.views import HelpQueryView, QueryView, RecentQueryView, ActionQueryView @@ -22,4 +22,5 @@ path('recent_queries/', RecentQueryView.as_view(), name='recent-queries'), path('query/', QueryView.as_view(), name='query'), path('help/', HelpQueryView.as_view(), name='help'), + path('action/', ActionQueryView.as_view(), name='action') ] diff --git a/apps/spotlight/views.py b/apps/spotlight/views.py index 54f5ae4..0be187b 100644 --- a/apps/spotlight/views.py +++ b/apps/spotlight/views.py @@ -2,12 +2,19 @@ from django.http import JsonResponse from django.db import transaction from rest_framework import generics +import requests +from django_q.tasks import async_task from apps.spotlight.models import Query from apps.spotlight.serializers import QuerySerializer from .service import HelpService, QueryService +from apps.workspaces.models import FyleCredential +from apps.fyle.helpers import get_access_token +code_action_map = { + "trigger_export": 'http://localhost:8000/api/workspaces/2/trigger_export/' +} # Create your views here. # class RecentQueryView(generics.ListAPIView): @@ -61,7 +68,6 @@ def post(self, request, *args, **kwargs): payload = json.loads(request.body) user_query = payload["query"] suggestions = QueryService.get_suggestions(user_query=user_query) - print("suggestions", suggestions) Query.objects.create( query=user_query, @@ -78,3 +84,26 @@ def post(self, request, *args, **kwargs): user_query = payload["query"] support_response = HelpService.get_support_response(user_query=user_query) return JsonResponse(data={"message": support_response}) + + +class ActionQueryView(generics.CreateAPIView): + def post(self, request, *args, **kwargs): + workspace_id = self.kwargs.get('workspace_id') + payload = json.loads(request.body) + code = payload["code"] + + creds = FyleCredential.objects.get(workspace_id=workspace_id) + + access_token = get_access_token(creds.refresh_token) + + try: + headers = { + "Authorization": f"Bearer {access_token}", + "Content-Type": "application/json" + } + action_response = requests.post(code_action_map[code], json={}, headers=headers) + print(action_response) + except Exception as e: + print(e) + + return JsonResponse(data={"message": "Action triggered successfully"}) \ No newline at end of file diff --git a/apps/workspaces/tasks.py b/apps/workspaces/tasks.py index a337d13..c69761e 100644 --- a/apps/workspaces/tasks.py +++ b/apps/workspaces/tasks.py @@ -100,3 +100,11 @@ def async_create_admin_subcriptions(workspace_id: int) -> None: 'webhook_url': '{}/workspaces/{}/fyle/webhook_callback/'.format(settings.API_URL, workspace_id) } platform.subscriptions.post(payload) + + +def trigger_export(workspace_id): + run_import_export(workspace_id=workspace_id) + new_expenses_imported = Expense.objects.filter( + workspace_id=workspace_id, exported=False + ).exists() + return new_expenses_imported \ No newline at end of file diff --git a/apps/workspaces/views.py b/apps/workspaces/views.py index 1f17221..b883771 100644 --- a/apps/workspaces/views.py +++ b/apps/workspaces/views.py @@ -16,7 +16,7 @@ WorkspaceSerializer, ExportSettingsSerializer, FieldMappingSerializer, AdvancedSettingSerializer ) -from .tasks import run_import_export +from .tasks import trigger_export class WorkspaceView(generics.CreateAPIView, generics.RetrieveAPIView): @@ -98,10 +98,7 @@ def post(self, request, *args, **kwargs): """ workspace_id = self.kwargs.get('workspace_id') - run_import_export(workspace_id=workspace_id) - new_expenses_imported = Expense.objects.filter( - workspace_id=workspace_id, exported=False - ).exists() + new_expenses_imported = trigger_export(workspace_id) return Response( status=status.HTTP_200_OK, From 70b7e49e20627024e08f3372811d43479cc3769f Mon Sep 17 00:00:00 2001 From: Shreyansh Sahare Date: Thu, 12 Sep 2024 12:31:38 +0530 Subject: [PATCH 12/25] action api --- apps/spotlight/service.py | 50 ++++++++++++++++++++++++++++++++++++++- apps/spotlight/views.py | 17 ++++--------- 2 files changed, 53 insertions(+), 14 deletions(-) diff --git a/apps/spotlight/service.py b/apps/spotlight/service.py index a091546..7455841 100644 --- a/apps/spotlight/service.py +++ b/apps/spotlight/service.py @@ -1,9 +1,19 @@ -from typing import Dict +from typing import Callable, Dict + +import requests + +from apps.fyle.helpers import get_access_token +from apps.workspaces.models import FyleCredential from .prompts.support_genie import PROMPT as SUPPORT_GENIE_PROMPT from .prompts.spotlight_prompt import PROMPT as SPOTLIGHT_PROMPT from . import llm +code_action_map = { + "trigger_export": 'http://localhost:8000/api/workspaces/2/trigger_export/' +} + + class HelpService: @classmethod def extract_citations(cls, *, citations: list) -> list: @@ -42,3 +52,41 @@ def get_suggestions(cls, *, user_query: str) -> str: user_query=user_query ) return llm.get_openai_response(system_prompt=formatted_prompt) + + +class ActionService: + + @classmethod + def _get_action_function_from_code(cls, *, code: str) -> Callable: + code_to_function_map = { + "trigger_export": cls.trigger_export + } + return code_to_function_map[code] + + @classmethod + def get_headers(cls, *, access_token: str) -> Dict: + return { + "Authorization": f"Bearer {access_token}", + "Content-Type": "application/json" + } + + @classmethod + def get_access_token(cls, *, workspace_id: int) -> str: + creds = FyleCredential.objects.get(workspace_id=workspace_id) + return get_access_token(creds.refresh_token) + + @classmethod + def trigger_export(cls, *, workspace_id: int): + access_token = cls.get_access_token(workspace_id=workspace_id) + headers = cls.get_headers(access_token=access_token) + headers = { + "Authorization": f"Bearer {access_token}", + "Content-Type": "application/json" + } + url = 'http://localhost:8000/api/workspaces/2/trigger_export/' + action_response = requests.post(url, json={}, headers=headers) + + @classmethod + def action(cls, *, code: str, workspace_id: str): + action_function = cls._get_action_function_from_code(code=code) + action_function(workspace_id=workspace_id) diff --git a/apps/spotlight/views.py b/apps/spotlight/views.py index 0be187b..4d61b0c 100644 --- a/apps/spotlight/views.py +++ b/apps/spotlight/views.py @@ -8,7 +8,7 @@ from apps.spotlight.models import Query from apps.spotlight.serializers import QuerySerializer -from .service import HelpService, QueryService +from .service import ActionService, HelpService, QueryService from apps.workspaces.models import FyleCredential from apps.fyle.helpers import get_access_token @@ -91,19 +91,10 @@ def post(self, request, *args, **kwargs): workspace_id = self.kwargs.get('workspace_id') payload = json.loads(request.body) code = payload["code"] - - creds = FyleCredential.objects.get(workspace_id=workspace_id) - - access_token = get_access_token(creds.refresh_token) try: - headers = { - "Authorization": f"Bearer {access_token}", - "Content-Type": "application/json" - } - action_response = requests.post(code_action_map[code], json={}, headers=headers) - print(action_response) + ActionService.action(code=code, workspace_id=workspace_id) + return JsonResponse(data={"message": "Action triggered successfully"}, status_code=200) except Exception as e: print(e) - - return JsonResponse(data={"message": "Action triggered successfully"}) \ No newline at end of file + return JsonResponse(data={"message": "Action failed"}, status_code=500) From ea568040c92535d8ba481856af6ba2da35dfbef0 Mon Sep 17 00:00:00 2001 From: Shreyansh Sahare Date: Thu, 12 Sep 2024 12:47:26 +0530 Subject: [PATCH 13/25] action api --- apps/spotlight/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/spotlight/views.py b/apps/spotlight/views.py index 4d61b0c..ad6511f 100644 --- a/apps/spotlight/views.py +++ b/apps/spotlight/views.py @@ -94,7 +94,7 @@ def post(self, request, *args, **kwargs): try: ActionService.action(code=code, workspace_id=workspace_id) - return JsonResponse(data={"message": "Action triggered successfully"}, status_code=200) + return JsonResponse(data={"message": "Action triggered successfully"}, status=200) except Exception as e: print(e) - return JsonResponse(data={"message": "Action failed"}, status_code=500) + return JsonResponse(data={"message": "Action failed"}, status=500) From 7cf4f49a1328f266ff9297e52b16b75cd91ce6d8 Mon Sep 17 00:00:00 2001 From: Shreyansh Sahare Date: Thu, 12 Sep 2024 12:58:58 +0530 Subject: [PATCH 14/25] action api --- apps/spotlight/service.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/spotlight/service.py b/apps/spotlight/service.py index 7455841..bfaff04 100644 --- a/apps/spotlight/service.py +++ b/apps/spotlight/service.py @@ -83,7 +83,7 @@ def trigger_export(cls, *, workspace_id: int): "Authorization": f"Bearer {access_token}", "Content-Type": "application/json" } - url = 'http://localhost:8000/api/workspaces/2/trigger_export/' + url = f'http://localhost:8000/api/workspaces/{workspace_id}/trigger_export/' action_response = requests.post(url, json={}, headers=headers) @classmethod From 160568bb92654a76aec0f5689d7a648be380395b Mon Sep 17 00:00:00 2001 From: Shreyansh Sahare Date: Thu, 12 Sep 2024 13:25:22 +0530 Subject: [PATCH 15/25] added action response --- apps/spotlight/service.py | 14 ++++++++++++-- apps/spotlight/views.py | 7 +++++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/apps/spotlight/service.py b/apps/spotlight/service.py index bfaff04..4c21561 100644 --- a/apps/spotlight/service.py +++ b/apps/spotlight/service.py @@ -1,3 +1,4 @@ +from dataclasses import dataclass from typing import Callable, Dict import requests @@ -14,6 +15,12 @@ } +@dataclass +class ActionResponse: + message: str = None + is_success: bool = None + + class HelpService: @classmethod def extract_citations(cls, *, citations: list) -> list: @@ -85,8 +92,11 @@ def trigger_export(cls, *, workspace_id: int): } url = f'http://localhost:8000/api/workspaces/{workspace_id}/trigger_export/' action_response = requests.post(url, json={}, headers=headers) + if action_response.status_code == 200: + return ActionResponse(message="Export triggered successfully", is_success=True) + return ActionResponse(message="Export triggered failed", is_success=False) @classmethod - def action(cls, *, code: str, workspace_id: str): + def action(cls, *, code: str, workspace_id: str) -> ActionResponse: action_function = cls._get_action_function_from_code(code=code) - action_function(workspace_id=workspace_id) + return action_function(workspace_id=workspace_id) diff --git a/apps/spotlight/views.py b/apps/spotlight/views.py index ad6511f..87f5355 100644 --- a/apps/spotlight/views.py +++ b/apps/spotlight/views.py @@ -93,8 +93,11 @@ def post(self, request, *args, **kwargs): code = payload["code"] try: - ActionService.action(code=code, workspace_id=workspace_id) - return JsonResponse(data={"message": "Action triggered successfully"}, status=200) + action_response = ActionService.action(code=code, workspace_id=workspace_id) + if action_response.is_success is True: + return JsonResponse(data={"message": action_response.message}, status=200) + else: + return JsonResponse(data={"message": action_response.message}, status=500) except Exception as e: print(e) return JsonResponse(data={"message": "Action failed"}, status=500) From 7d27cd57e0d98d3b8a10767cfe39527fa31bfb4e Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Thu, 12 Sep 2024 15:22:55 +0530 Subject: [PATCH 16/25] Field mapping changes --- apps/spotlight/service.py | 87 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 82 insertions(+), 5 deletions(-) diff --git a/apps/spotlight/service.py b/apps/spotlight/service.py index 4c21561..7796349 100644 --- a/apps/spotlight/service.py +++ b/apps/spotlight/service.py @@ -1,5 +1,6 @@ from dataclasses import dataclass from typing import Callable, Dict +import json import requests @@ -10,9 +11,6 @@ from . import llm -code_action_map = { - "trigger_export": 'http://localhost:8000/api/workspaces/2/trigger_export/' -} @dataclass @@ -66,7 +64,11 @@ class ActionService: @classmethod def _get_action_function_from_code(cls, *, code: str) -> Callable: code_to_function_map = { - "trigger_export": cls.trigger_export + "trigger_export": cls.trigger_export, + "set_customer_field_mapping_to_project": cls.set_customer_field_mapping_to_project, + "set_customer_field_mapping_to_cost_center": cls.set_customer_field_mapping_to_cost_center, + "set_class_field_mapping_to_project": cls.set_class_field_mapping_to_project, + "set_class_field_mapping_to_cost_center": cls.set_class_field_mapping_to_cost_center } return code_to_function_map[code] @@ -97,6 +99,81 @@ def trigger_export(cls, *, workspace_id: int): return ActionResponse(message="Export triggered failed", is_success=False) @classmethod - def action(cls, *, code: str, workspace_id: str) -> ActionResponse: + def set_customer_field_mapping_to_project(cls, *, workspace_id: int): + access_token = cls.get_access_token(workspace_id=workspace_id) + headers = cls.get_headers(access_token=access_token) + headers = { + "Authorization": f"Bearer {access_token}", + "Content-Type": "application/json" + } + url = f'http://localhost:8000/api/workspaces/{workspace_id}/field_mappings/' + headers = { + "Authorization": f"Bearer {access_token}", + "Content-Type": "application/json" + } + action_response = requests.get(url, headers=headers) + action_response= action_response.json() + if action_response.get('project_type') != 'PROJECT' and action_response.get('class_type') != 'COST_CENTER': + action_response['project_type'] = 'PROJECT' + post_response = requests.post(url, headers=headers, data=json.dumps(action_response)) + return ActionResponse(message="Field mapping updated successfully", is_success=True) + return ActionResponse(message="Field mapping already exists", is_success=False) + + @classmethod + def set_customer_field_mapping_to_cost_center(cls, *, workspace_id: int): + access_token = cls.get_access_token(workspace_id=workspace_id) + headers = cls.get_headers(access_token=access_token) + headers = { + "Authorization": f"Bearer {access_token}", + "Content-Type": "application/json" + } + url = f'http://localhost:8000/api/workspaces/{workspace_id}/field_mappings/' + + action_response = requests.get(url, headers=headers) + action_response= action_response.json() + if action_response.get('project_type') != 'COST_CENTER' and action_response.get('class_type') != 'PROJECT': + action_response['project_type'] = 'COST_CENTER' + post_response = requests.post(url, headers=headers, data=json.dumps(action_response)) + return ActionResponse(message="Field mapping updated successfully", is_success=True) + return ActionResponse(message="Field mapping already exists", is_success=False) + + @classmethod + def set_class_field_mapping_to_project(cls, *, workspace_id: int): + access_token = cls.get_access_token(workspace_id=workspace_id) + headers = cls.get_headers(access_token=access_token) + headers = { + "Authorization": f"Bearer {access_token}", + "Content-Type": "application/json" + } + url = f'http://localhost:8000/api/workspaces/{workspace_id}/field_mappings/' + + action_response = requests.get(url, headers=headers) + action_response= action_response.json() + if action_response.get('project_type') != 'PROJECT' and action_response.get('class_type') != 'COST_CENTER': + action_response['class_type'] = 'PROJECT' + post_response = requests.post(url, headers=headers, data=json.dumps(action_response)) + return ActionResponse(message="Field mapping updated successfully", is_success=True) + return ActionResponse(message="Field mapping already exists", is_success=False) + + @classmethod + def set_class_field_mapping_to_cost_center(cls, *, workspace_id: int): + access_token = cls.get_access_token(workspace_id=workspace_id) + headers = cls.get_headers(access_token=access_token) + headers = { + "Authorization": f"Bearer {access_token}", + "Content-Type": "application/json" + } + url = f'http://localhost:8000/api/workspaces/{workspace_id}/field_mappings/' + + action_response = requests.get(url, headers=headers) + action_response= action_response.json() + if action_response.get('project_type') != 'COST_CENTER' and action_response.get('class_type') != 'PROJECT': + action_response['class_type'] = 'COST_CENTER' + post_response = requests.post(url, headers=headers, data=json.dumps(action_response)) + return ActionResponse(message="Field mapping updated successfully", is_success=True) + return ActionResponse(message="Field mapping already exists", is_success=False) + + @classmethod + def action(cls, *, code: str, workspace_id: str): action_function = cls._get_action_function_from_code(code=code) return action_function(workspace_id=workspace_id) From 0e06bbcb3e5a9c9993005a2c499cc746663e7648 Mon Sep 17 00:00:00 2001 From: Shreyansh Sahare Date: Thu, 12 Sep 2024 15:30:02 +0530 Subject: [PATCH 17/25] reimbursable expense field set --- apps/spotlight/service.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/apps/spotlight/service.py b/apps/spotlight/service.py index 7796349..90069f1 100644 --- a/apps/spotlight/service.py +++ b/apps/spotlight/service.py @@ -1,11 +1,12 @@ from dataclasses import dataclass from typing import Callable, Dict +from django.db import transaction import json import requests from apps.fyle.helpers import get_access_token -from apps.workspaces.models import FyleCredential +from apps.workspaces.models import ExportSettings, FyleCredential from .prompts.support_genie import PROMPT as SUPPORT_GENIE_PROMPT from .prompts.spotlight_prompt import PROMPT as SPOTLIGHT_PROMPT @@ -65,6 +66,7 @@ class ActionService: def _get_action_function_from_code(cls, *, code: str) -> Callable: code_to_function_map = { "trigger_export": cls.trigger_export, + "set_reimbursable_expenses_export_module_bill": cls.set_reimbursable_expenses_export_module_bill, "set_customer_field_mapping_to_project": cls.set_customer_field_mapping_to_project, "set_customer_field_mapping_to_cost_center": cls.set_customer_field_mapping_to_cost_center, "set_class_field_mapping_to_project": cls.set_class_field_mapping_to_project, @@ -84,6 +86,19 @@ def get_access_token(cls, *, workspace_id: int) -> str: creds = FyleCredential.objects.get(workspace_id=workspace_id) return get_access_token(creds.refresh_token) + @classmethod + def set_reimbursable_expenses_export_module_bill(cls, *, workspace_id: int): + with transaction.atomic(): + export_settings = ExportSettings.objects.filter( + workspace_id=workspace_id + ).first() + if export_settings is None: + return ActionResponse(message="Failed to set reimbursable expense export type set to Bill", is_success=False) + else: + export_settings.reimbursable_expenses_export_type = 'BILL' + export_settings.save() + return ActionResponse(message="Reimbursable expense export type set to Bill", is_success=True) + @classmethod def trigger_export(cls, *, workspace_id: int): access_token = cls.get_access_token(workspace_id=workspace_id) From 5f33e7a609df6f5708fb66491615bceb76ea616f Mon Sep 17 00:00:00 2001 From: Shreyansh Sahare Date: Thu, 12 Sep 2024 15:33:46 +0530 Subject: [PATCH 18/25] reimbursable expense field set journal entry --- apps/spotlight/service.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/apps/spotlight/service.py b/apps/spotlight/service.py index 90069f1..a3da0fd 100644 --- a/apps/spotlight/service.py +++ b/apps/spotlight/service.py @@ -67,6 +67,7 @@ def _get_action_function_from_code(cls, *, code: str) -> Callable: code_to_function_map = { "trigger_export": cls.trigger_export, "set_reimbursable_expenses_export_module_bill": cls.set_reimbursable_expenses_export_module_bill, + "set_reimbursable_expenses_export_module_journal_entry": cls.set_reimbursable_expenses_export_module_journal_entry, "set_customer_field_mapping_to_project": cls.set_customer_field_mapping_to_project, "set_customer_field_mapping_to_cost_center": cls.set_customer_field_mapping_to_cost_center, "set_class_field_mapping_to_project": cls.set_class_field_mapping_to_project, @@ -99,6 +100,19 @@ def set_reimbursable_expenses_export_module_bill(cls, *, workspace_id: int): export_settings.save() return ActionResponse(message="Reimbursable expense export type set to Bill", is_success=True) + @classmethod + def set_reimbursable_expenses_export_module_journal_entry(cls, *, workspace_id: int): + with transaction.atomic(): + export_settings = ExportSettings.objects.filter( + workspace_id=workspace_id + ).first() + if export_settings is None: + return ActionResponse(message="Failed to set reimbursable expense export type set to Journal Entry", is_success=False) + else: + export_settings.reimbursable_expenses_export_type = 'JOURNAL_ENTRY' + export_settings.save() + return ActionResponse(message="Reimbursable expense export type set to Journal Entry", is_success=True) + @classmethod def trigger_export(cls, *, workspace_id: int): access_token = cls.get_access_token(workspace_id=workspace_id) From af12a546f7eafaf7cc6d705c96ef691a9474cdc0 Mon Sep 17 00:00:00 2001 From: Ashutosh619-sudo Date: Thu, 12 Sep 2024 15:44:30 +0530 Subject: [PATCH 19/25] added more actions --- apps/spotlight/service.py | 61 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/apps/spotlight/service.py b/apps/spotlight/service.py index a3da0fd..5de9056 100644 --- a/apps/spotlight/service.py +++ b/apps/spotlight/service.py @@ -13,7 +13,6 @@ from . import llm - @dataclass class ActionResponse: message: str = None @@ -71,7 +70,11 @@ def _get_action_function_from_code(cls, *, code: str) -> Callable: "set_customer_field_mapping_to_project": cls.set_customer_field_mapping_to_project, "set_customer_field_mapping_to_cost_center": cls.set_customer_field_mapping_to_cost_center, "set_class_field_mapping_to_project": cls.set_class_field_mapping_to_project, - "set_class_field_mapping_to_cost_center": cls.set_class_field_mapping_to_cost_center + "set_class_field_mapping_to_cost_center": cls.set_class_field_mapping_to_cost_center, + "set_corporate_credit_card_expenses_export_credit_card_purchase": cls.set_cc_export_to_corporate_card_purchase, + "set_corporate_credit_card_expenses_export_journal_entry": cls.set_cc_export_to_journal_entry, + "set_corporate_credit_card_expenses_export_grouping_report": cls.set_cc_grouping_to_report, + "set_corporate_credit_card_expenses_export_grouping_expense": cls.set_cc_grouping_to_expense, } return code_to_function_map[code] @@ -127,6 +130,60 @@ def trigger_export(cls, *, workspace_id: int): return ActionResponse(message="Export triggered successfully", is_success=True) return ActionResponse(message="Export triggered failed", is_success=False) + + @classmethod + def set_cc_export_to_corporate_card_purchase(cls, *, workspace_id: int): + with transaction.atomic(): + export_settings = ExportSettings.objects.filter(workspace_id=workspace_id).first() + if export_settings: + export_settings.credit_card_expense_export_type = 'CREDIT_CARD_PURCHASE' + export_settings.save() + return ActionResponse(message="Successfully set corporate card expense as Credit Card Purchase", is_success=True) + + return ActionResponse(message="Export settings doesn't exists!", is_success=False) + + + @classmethod + def set_cc_export_to_journal_entry(cls, *, workspace_id: int): + with transaction.atomic(): + export_settings = ExportSettings.objects.filter(workspace_id=workspace_id).first() + if export_settings: + export_settings.credit_card_expense_export_type = 'JOURNAL_ENTRY' + export_settings.save() + return ActionResponse(message="Successfully set corporate card expense as JOURNAL ENTRY", is_success=True) + + return ActionResponse(message="Export settings doesn't exists!", is_success=False) + + @classmethod + def set_cc_grouping_to_report(cls, *, workspace_id: int): + with transaction.atomic(): + export_settings = ExportSettings.objects.filter(workspace_id=workspace_id).first() + if export_settings: + if export_settings.credit_card_expense_export_type == 'CREDIT_CARD_PURCHASE': + return ActionResponse(message='For Corporate Credit Purchase Export type expenses cannot be grouped by report', is_success=False) + else: + export_settings.credit_card_expense_grouped_by = 'REPORT' + export_settings.save() + return ActionResponse(message='Succesfully set corporate card group by to Report', is_success=True) + + return ActionResponse(message="Export settings doesn't exists!", is_success=False) + + + @classmethod + def set_cc_grouping_to_expense(cls, *, workspace_id: int): + with transaction.atomic(): + export_settings = ExportSettings.objects.filter(workspace_id=workspace_id).first() + if export_settings: + if export_settings.credit_card_expense_export_type == 'CREDIT_CARD_PURCHASE': + return ActionResponse(message='Already set to expense', is_success=True) + else: + export_settings.credit_card_expense_grouped_by = 'EXPENSE' + export_settings.save() + return ActionResponse(message='Succesfully set corporate card group by to EXPENSE', is_success=True) + + return ActionResponse(message="Export settings doesn't exists!", is_success=False) + + @classmethod def set_customer_field_mapping_to_project(cls, *, workspace_id: int): access_token = cls.get_access_token(workspace_id=workspace_id) From 0689b79630f2cd2351fe5df645a8cfd3085ddab1 Mon Sep 17 00:00:00 2001 From: Shreyansh Sahare Date: Thu, 12 Sep 2024 15:50:49 +0530 Subject: [PATCH 20/25] reimbursable expense grouping api --- apps/spotlight/prompts/spotlight_prompt.py | 4 ++-- apps/spotlight/service.py | 28 ++++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/apps/spotlight/prompts/spotlight_prompt.py b/apps/spotlight/prompts/spotlight_prompt.py index 3c00bd6..ee38ca7 100644 --- a/apps/spotlight/prompts/spotlight_prompt.py +++ b/apps/spotlight/prompts/spotlight_prompt.py @@ -88,8 +88,8 @@ "description": "Set grouping to expense, this grouping reflects how the expense entries are posted in QuickBooks Desktop." }}, {{ - "code": "set_reimbursable_expenses_export_grouping_expense_report", - "title": "Group reimbursable expenses export by expense report", + "code": "set_reimbursable_expenses_export_grouping_report", + "title": "Group reimbursable expenses export by report", "description": "Set grouping to expense_report, this grouping reflects how the expense entries are posted in QuickBooks Desktop." }}, {{ diff --git a/apps/spotlight/service.py b/apps/spotlight/service.py index 5de9056..b4aa2f4 100644 --- a/apps/spotlight/service.py +++ b/apps/spotlight/service.py @@ -67,6 +67,8 @@ def _get_action_function_from_code(cls, *, code: str) -> Callable: "trigger_export": cls.trigger_export, "set_reimbursable_expenses_export_module_bill": cls.set_reimbursable_expenses_export_module_bill, "set_reimbursable_expenses_export_module_journal_entry": cls.set_reimbursable_expenses_export_module_journal_entry, + "set_reimbursable_expenses_export_grouping_expense": cls.set_reimbursable_expenses_export_grouping_expense, + "set_reimbursable_expenses_export_grouping_report": cls.set_reimbursable_expenses_export_grouping_report, "set_customer_field_mapping_to_project": cls.set_customer_field_mapping_to_project, "set_customer_field_mapping_to_cost_center": cls.set_customer_field_mapping_to_cost_center, "set_class_field_mapping_to_project": cls.set_class_field_mapping_to_project, @@ -116,6 +118,32 @@ def set_reimbursable_expenses_export_module_journal_entry(cls, *, workspace_id: export_settings.save() return ActionResponse(message="Reimbursable expense export type set to Journal Entry", is_success=True) + @classmethod + def set_reimbursable_expenses_export_grouping_expense(cls, *, workspace_id: int): + with transaction.atomic(): + export_settings = ExportSettings.objects.filter( + workspace_id=workspace_id + ).first() + if export_settings is None: + return ActionResponse(message="Failed to set reimbursable expense export grouping to Expenses", is_success=False) + else: + export_settings.reimbursable_expense_grouped_by = 'EXPENSE' + export_settings.save() + return ActionResponse(message="Reimbursable expense export group set to Expenses", is_success=True) + + @classmethod + def set_reimbursable_expenses_export_grouping_report(cls, *, workspace_id: int): + with transaction.atomic(): + export_settings = ExportSettings.objects.filter( + workspace_id=workspace_id + ).first() + if export_settings is None: + return ActionResponse(message="Failed to set reimbursable expense export grouping to Report", is_success=False) + else: + export_settings.reimbursable_expense_grouped_by = 'REPORT' + export_settings.save() + return ActionResponse(message="Reimbursable expense export group set to Report", is_success=True) + @classmethod def trigger_export(cls, *, workspace_id: int): access_token = cls.get_access_token(workspace_id=workspace_id) From 93b3e313db908caac70f6e20eafe0fcdfc0970ed Mon Sep 17 00:00:00 2001 From: Shreyansh Sahare Date: Thu, 12 Sep 2024 15:57:35 +0530 Subject: [PATCH 21/25] reimbursable expense export state --- apps/spotlight/service.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/apps/spotlight/service.py b/apps/spotlight/service.py index b4aa2f4..6cf0528 100644 --- a/apps/spotlight/service.py +++ b/apps/spotlight/service.py @@ -69,6 +69,8 @@ def _get_action_function_from_code(cls, *, code: str) -> Callable: "set_reimbursable_expenses_export_module_journal_entry": cls.set_reimbursable_expenses_export_module_journal_entry, "set_reimbursable_expenses_export_grouping_expense": cls.set_reimbursable_expenses_export_grouping_expense, "set_reimbursable_expenses_export_grouping_report": cls.set_reimbursable_expenses_export_grouping_report, + "set_reimbursable_expenses_export_state_processing": cls.set_reimbursable_expenses_export_state_processing, + "set_reimbursable_expenses_export_state_paid": cls.set_reimbursable_expenses_export_state_paid, "set_customer_field_mapping_to_project": cls.set_customer_field_mapping_to_project, "set_customer_field_mapping_to_cost_center": cls.set_customer_field_mapping_to_cost_center, "set_class_field_mapping_to_project": cls.set_class_field_mapping_to_project, @@ -144,6 +146,32 @@ def set_reimbursable_expenses_export_grouping_report(cls, *, workspace_id: int): export_settings.save() return ActionResponse(message="Reimbursable expense export group set to Report", is_success=True) + @classmethod + def set_reimbursable_expenses_export_state_processing(cls, *, workspace_id: int): + with transaction.atomic(): + export_settings = ExportSettings.objects.filter( + workspace_id=workspace_id + ).first() + if export_settings is None: + return ActionResponse(message="Failed to set reimbursable expense export state to Processing", is_success=False) + else: + export_settings.reimbursable_expense_state = 'PAYMENT_PROCESSING' + export_settings.save() + return ActionResponse(message="Reimbursable expense export state set to Processing", is_success=True) + + @classmethod + def set_reimbursable_expenses_export_state_paid(cls, *, workspace_id: int): + with transaction.atomic(): + export_settings = ExportSettings.objects.filter( + workspace_id=workspace_id + ).first() + if export_settings is None: + return ActionResponse(message="Failed to set reimbursable expense export state to Paid", is_success=False) + else: + export_settings.reimbursable_expense_state = 'PAID' + export_settings.save() + return ActionResponse(message="Reimbursable expense export state set to Paid", is_success=True) + @classmethod def trigger_export(cls, *, workspace_id: int): access_token = cls.get_access_token(workspace_id=workspace_id) From aaf0e82babfaa9127d62a036653cb4c5d3fb6433 Mon Sep 17 00:00:00 2001 From: Shreyansh Sahare Date: Thu, 12 Sep 2024 19:23:34 +0530 Subject: [PATCH 22/25] updated help section prompt --- apps/spotlight/prompts/spotlight_prompt.py | 163 ++++++++++++--------- 1 file changed, 92 insertions(+), 71 deletions(-) diff --git a/apps/spotlight/prompts/spotlight_prompt.py b/apps/spotlight/prompts/spotlight_prompt.py index ee38ca7..e22eb3b 100644 --- a/apps/spotlight/prompts/spotlight_prompt.py +++ b/apps/spotlight/prompts/spotlight_prompt.py @@ -191,88 +191,103 @@ "code": "go_to_dashboard", "title": "Go to Dashboard", "description": "Navigate to the IIF file management section for import/export options.", - "url": "https://example.com/dashboard" + "url": "/dashboard" }}, {{ "code": "go_to_settings", "title": "Go to Export Settings", "description": "Navigate to the export settings section to manage export configurations.", - "url": "https://example.com/settings" + "url": "/configuration/export_settings" }}, {{ "code": "go_to_field_mappings", "title": "Go to Field Mappings", "description": "Navigate to the Field Mapping Settings Section to manage Field Mapping Settings.", - "url": "https://example.com/field_mappings" + "url": "/configuration/field_mapping" }}, {{ "code": "go_to_advanced_settings", "title": "Go to Advanced Settings", "description": "Navigate to the advanced settings section to manage automatic export settings.", - "url": "https://example.com/advanced_settings" + "url": "/configuration/advanced_settings" }}, {{ "code": "go_to_mappings", "title": "Go to Mappings Page", "description": "Navigate to the field mapping section to configure mappings.", - "url": "https://example.com/mappings" + "url": "/mapping/corporate_card" }} ] -------------------- -Help Intructions: - 1. Provide specific help suggestions based on the user's search query. - 2. Each help suggestion should have a unique code, title, and a brief description. +Help Instructions: + 1. Formulate a question based on the user's search query in description. + 2. The question should be formulated to QBD as a context of question. 3. The help suggestion should offer guidance or explanations related to the user's search query. - 4. IMPORTANT: Only choose help suggestions from the examples given below. - 5. Interpret the user's search query to suggest relevant help options. - 6. Ignore spelling errors and variations in the user's search query. - 7. Suggest the best help that matches the user's search query. + 4. Ignore spelling errors and variations in the user's search query. - Help Map: - "help": [ - {{ - "code": "learn_export", - "title": "Learn more about IIF export", - "description": "How to export IIF File?." - }}, - {{ - "code": "date_filter_help", - "title": "How to filter IIF files by date", - "description": "How to filter by date in QBD?" - }}, - {{ - "code": "learn_export_settings", - "title": "Learn more about export settings", - "description": "how to manage and configure export settings." - }}, - {{ - "code": "configure_credit_card_mapping", - "title": "How to configure credit card mapping", - "description": "how to set up field mappings for credit card transactions." - }}, - {{ - "code": "field_mapping_help", - "title": "How to create field mappings", - "description": "how to create new field mappings for import/export." - }}, - {{ - "code": "automatic_export_help", - "title": "How to set up automatic export", - "description": "how to configure automatic export settings for your data." - }}, - {{ - "code": "memo_field_help", - "title": "How to use memo field in export", - "description": "how to properly set and use the memo field in data exports." - }}, - {{ - "code": "map_fields_help", - "title": "How to map fields", - "description": "how to map fields for accurate data handling and export." - }} - ] + Examples: + 1. User Query Inputs: ["How to export IIF files?", "export IIF files", "IIF export", "learn how to export IIF files", "export to IIF", "how to export data to IIF", "IIF file export", "guide to exporting IIF files", "learn export", "IIF file", "how to export", "export instructions", "IIF export process"] + + Output: + {{ + "code": "learn_export", + "title": "Learn more about IIF export", + "description": "How to export IIF File in QBD?." + }} + 2. User Query Inputs: ["Disable reimbursable expenses", "disable reimbursable export", "turn off reimbursable export", "stop exporting reimbursable expenses", "disable reimbursable expenses export", "disable export settings for reimbursable expenses", "deactivate reimbursable export", "disable reimbursable export settings", "turn off export for reimbursable expenses", "stop reimbursable export"] + + Output: + {{ + "code": "disable_reimbursable_expenses_export", + "title": "Disable reimbursable export settings", + "description": "Disable the option to export reimbursable expenses in Export Configuration in QBD." + }} + 3. User Query: ["How to manage IIF files?", "manage IIF files", "IIF file management", "how to filter IIF files", "filter IIF files by date", "manage files in QBD", "IIF file filters", "filter IIF data", "how to filter by date in QuickBooks Desktop", "date filters in IIF files", "QBD IIF file management", "file management in QuickBooks Desktop", "IIF file organization"] + + Output: + {{ + "code": "date_filter_help", + "title": "How to filter IIF files by date", + "description": "How to filter by date in QBD?" + }} + 4. User Query: "How to map fields?" + {{ + "code": "configure_credit_card_mapping", + "title": "How to configure credit card mapping", + "description": "how to set up field mappings for credit card transactions in QBD." + }} + 5. User Query: "How to create field mappings?" + {{ + "code": "field_mapping_help", + "title": "How to create field mappings", + "description": "how to create new field mappings for import/export in QBD." + }} + 6. User Query: "How to set up automatic export?" + {{ + "code": "automatic_export_help", + "title": "How to set up automatic export", + "description": "how to configure automatic export settings for your data in QBD." + }} + 7. User Query: "How to use memo field in export?" + {{ + "code": "memo_field_help", + "title": "How to use memo field in export", + "description": "how to properly set and use the memo field in data exports in QBD." + }} + 8. User Query: "How to map fields?" + {{ + "code": "map_fields_help", + "title": "How to map fields", + "description": "how to map fields for accurate data handling and export in QBD." + }} + 9. User Query: "How to create new field mappings?" + {{ + "code": "set_automatic_export", + "title": "Set/Update automatic export settings", + "description": "how to create new field mappings for import/export in QBD." + }} --------------------------- User Query: {user_query} @@ -295,7 +310,7 @@ {{ "code": "go_to_dashboard", "title": "Go to Dashboard", - "url": "https://example.com/dashboard", + "url": "/dashboard", "description": "Navigate to the IIF file management section for import/export options." }} ], @@ -303,7 +318,7 @@ {{ "code": "learn_export", "title": "Learn more about IIF export", - "description": "How to export IIF files?" + "description": "How to export IIF files in QBD?" }} ] }} @@ -359,8 +374,8 @@ "help": [ {{ "code": "learn_export_settings", - "title": "Learn more about export settings", - "description": "How to manage and configure export settings?" + "title": "Learn more about reimbursable expenses export settings", + "description": "How to enable or disable reimbursable export settings in QBD?" }} ], "navigations": [ @@ -368,7 +383,7 @@ "code": "go_to_settings", "title": "Go to Export Settings", "description": "Navigate to the export settings section to manage export configurations.", - "url": "https://example.com/settings" + "url": "/configuration/export_settings" }} ] }} @@ -406,14 +421,14 @@ "code": "go_to_field_mappings", "title": "Go to Field Mappings", "description": "Navigate to the Field Mapping Settings Section to manage Field Mapping Settings.", - "url": "https://example.com/field_mappings" + "url": "/configuration/field_mapping" }} ], "help": [ {{ "code": "field_mapping_help", "title": "How to create field mappings", - "description": "How to create new field mappings for import/export." + "description": "How to create new field mappings for import/export in QBD?" }} ] }} @@ -436,14 +451,14 @@ "code": "go_to_advanced_settings", "title": "Go to Advanced Settings", "description": "Navigate to the advanced settings section to manage automatic export settings.", - "url": "https://example.com/advanced_settings + "url": "/configuration/advanced_settings" }} ], "help": [ {{ "code": "automatic_export_help", "title": "How to set up automatic export", - "description": "how to configure automatic export settings for your data?" + "description": "how to configure automatic export settings for your data in QBD?" }} ] }} @@ -465,7 +480,7 @@ {{ "code": "memo_field_help", "title": "How to use memo field in export", - "description": "how to properly set and use the memo field in data exports?" + "description": "how to properly set and use the memo field in data exports in QBD?" }} ], "navigations": [ @@ -473,7 +488,7 @@ "code": "go_to_advanced_settings", "title": "Go to Advanced Settings", "description": "Navigate to the advanced settings section to configure memo field settings.", - "url": "https://example.com/advanced_settings" + "url": "/configuration/advanced_settings" }} ] }} @@ -494,15 +509,21 @@ {{ "code": "map_fields_help", "title": "How to map fields", - "description": "how to map fields for accurate data handling and export?" + "description": "how to map fields for accurate data handling and export in QBD?" }} ], "navigations": [ {{ - "code": "go_to_mappings", - "title": "Go to Mappings Page", - "description": "Navigate to the field mapping section to configure mappings.", - url: "https://example.com/mappings" + "code": "go_to_corporate_cards_mappings", + "title": "Go to Corporate Card Mappings Page", + "description": "Navigate to the corporate card field mapping section to configure mappings.", + url: "/mapping/corporate_card" + }}, + {{ + "code": "go_to_items_mappings", + "title": "Go to Items Mappings Page", + "description": "Navigate to the items field mapping section to configure mappings.", + url: "/mapping/item" }} ] }} From 023c3350abd7261bb40f6243c1116f28a897743c Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Fri, 13 Sep 2024 01:42:42 +0530 Subject: [PATCH 23/25] Add type --- apps/spotlight/prompts/spotlight_prompt.py | 283 +++++++++++++++------ 1 file changed, 210 insertions(+), 73 deletions(-) diff --git a/apps/spotlight/prompts/spotlight_prompt.py b/apps/spotlight/prompts/spotlight_prompt.py index e22eb3b..2b8716d 100644 --- a/apps/spotlight/prompts/spotlight_prompt.py +++ b/apps/spotlight/prompts/spotlight_prompt.py @@ -19,25 +19,31 @@ "suggestions": {{ "actions" : [ {{ + "type": "action", "code": "unique code for the action", "title": "suggest title" - "description": "brief description of the suggestion" + "description": "brief description of the suggestion", + "icon": "icon code" }}, // ... up to two actions ], "navigations": [ {{ + "type": "navigation", "code": "unique code for the navigation", "title": "suggest title" "description": "brief description of the suggestion", - "url": "URL to navigate to" + "url": "URL to navigate to", + "icon": "icon code" }}, // ... up to two navigations ], "help": [ {{, + "type": "help", "title": "suggest title" - "description": "form a question based on user question" + "description": "form a question based on user question", + "icon": "icon code" }}, // ... up to two help suggestions ] @@ -58,119 +64,165 @@ Actions Map: "actions" : [ {{ + "type": "action", "code": "trigger_export", "title": "Export IIF file", - "description": "Export the current data to an IIF file." + "description": "Export the current data to an IIF file.", + "icon": "pi-file-export" }}, {{ + "type": "action", "code": "enable_reimbursable_expenses_export", "title": "Enable reimbursable export settings", - "description": "Enable the option to export reimbursable expenses in Export Configuration." + "description": "Enable the option to export reimbursable expenses in Export Configuration.", + "icon": "pi-check" }}, {{ + "type": "action", "code": "disable_reimbursable_expenses_export", "title": "Disable reimbursable export settings", - "description": "Disable the option to export reimbursable expenses in Export Configuration." + "description": "Disable the option to export reimbursable expenses in Export Configuration.", + "icon": "pi-times" }}, {{ + "type": "action", "code": "set_reimbursable_expenses_export_module_bill", "title": "Select reimbursable export module as bill", - "description": "Choose Bill as the type of transaction in QuickBooks Desktop to export your Fyle expenses." + "description": "Choose Bill as the type of transaction in QuickBooks Desktop to export your Fyle expenses.", + "icon": "pi-list-check" }}, {{ + "type": "action", "code": "set_reimbursable_expenses_export_module_journal_entry", "title": "Select reimbursable export module as journal entry", - "description": "Choose Journal Entry as the type of transaction in QuickBooks Desktop to export your Fyle expenses." + "description": "Choose Journal Entry as the type of transaction in QuickBooks Desktop to export your Fyle expenses.", + "icon": "pi-list-check" }}, {{ + "type": "action", "code": "set_reimbursable_expenses_export_grouping_expense" "title": "Group reimbursable expenses export by expense", - "description": "Set grouping to expense, this grouping reflects how the expense entries are posted in QuickBooks Desktop." + "description": "Set grouping to expense, this grouping reflects how the expense entries are posted in QuickBooks Desktop.", + "icon": "pi-list-check" }}, {{ + "type": "action", "code": "set_reimbursable_expenses_export_grouping_report", "title": "Group reimbursable expenses export by report", - "description": "Set grouping to expense_report, this grouping reflects how the expense entries are posted in QuickBooks Desktop." + "description": "Set grouping to expense_report, this grouping reflects how the expense entries are posted in QuickBooks Desktop.", + "icon": "pi-list-check" }}, {{ + "type": "action", "code": "set_reimbursable_expenses_export_state_processing", "title": "Set reimbursable expenses export state as processing", - "description": "You could choose to export expenses when they have been approved and are awaiting payment clearance." + "description": "You could choose to export expenses when they have been approved and are awaiting payment clearance.", + "icon": "pi-list-check" }}, {{ + "type": "action", "code": "set_reimbursable_expenses_export_state_paid", "title": "Set reimbursable expenses export state as paid", - "description": "You could choose to export expenses when they have been paid out." + "description": "You could choose to export expenses when they have been paid out.", + "icon": "pi-list-check" }}, {{ + "type": "action", "code": "enable_corporate_card_expenses_export", "title": "Enable option corporate card expenses export", - "description": "Enable the option to export of credit card expenses from Fyle to QuickBooks Desktop." + "description": "Enable the option to export of credit card expenses from Fyle to QuickBooks Desktop.", + "icon": "pi-list-check" }}, {{ + "type": "action", "code": "disable_corporate_card_expenses_export", "title": "Disable reimbursable export settings", - "description": "Disable the option to export of credit card expenses from Fyle to QuickBooks Desktop." + "description": "Disable the option to export of credit card expenses from Fyle to QuickBooks Desktop.", + "icon": "pi-list-check" }}, {{ + "type": "action", "code": "set_corporate_credit_card_expenses_export_credit_card_purchase", - "title": "Set Credit Card Purchase transaction type to export", - "description": "Credit Card Purchase type of transaction in QuickBooks Desktop to be export as Fyle expenses." + "title": "Select Corporate Credit Card export module as credit card purchase", + "description": "Credit Card Purchase type of transaction in QuickBooks Desktop to be export as Fyle expenses.", + "icon": "pi-list-check" }}, {{ + "type": "action", "code": "set_corporate_credit_card_expenses_export_journal_entry", - "title": "Set Journal Entry transaction type to export", - "description": "Journal Entry type of transaction in QuickBooks Desktop to be export as Fyle expenses." + "title": "Select Corporate Credit Card export module as journal entry", + "description": "Journal Entry type of transaction in QuickBooks Desktop to be export as Fyle expenses.", + "icon": "pi-list-check" }}, {{ + "type": "action", "code": "set_corporate_credit_card_expenses_purchased_from_field_employee", - "title": "Set Purchased From field to Employee", - "description": "Employee field should be represented as Payee for the credit card purchase." + "title": "Set Corporate Credit Card Purchase field to Employee", + "description": "Employee field should be represented as Payee for the credit card purchase.", + "icon": "pi-list-check" }}, {{ + "type": "action", "code": "set_corporate_credit_card_expenses_purchased_from_field_vendor", - "title": "Set Purchased From field to Vendor", - "description": "Vendor field should be represented as Payee for the credit card purchase." + "title": "Set Corporate Credit Card Purchase field to Vendor", + "description": "Vendor field should be represented as Payee for the credit card purchase.", + "icon": "pi-list-check" }}, {{ + "type": "action", "code": "set_corporate_credit_card_expenses_export_grouping_report", "title": "Group corporate credit expenses export to report", - "description": "Group reports as the expense entries posted in QuickBooks Desktop." + "description": "Group reports as the expense entries posted in QuickBooks Desktop.", + "icon": "pi-list-check" }}, {{ + "type": "action", "code": "set_corporate_credit_card_expenses_export_grouping_expense", "title": "Group corporate credit expenses export to expenses", - "description": "Group expense as the expense entries posted in QuickBooks Desktop." + "description": "Group expense as the expense entries posted in QuickBooks Desktop.", + "icon": "pi-list-check" }}, {{ + "type": "action", "code": "set_corporate_credit_card_expenses_export_state_approved", "title": "Set corporate credit expenses export to approved state", - "description": "Set corporate credit expenses to export expenses when they have been approved and are awaiting payment clearance" + "description": "Set corporate credit expenses to export expenses when they have been approved and are awaiting payment clearance", + "icon": "pi-list-check" }}, {{ + "type": "action", "code": "set_corporate_credit_card_expenses_export_state_closed", "title": "Set corporate credit expenses export to closed state", - "description": "Set corporate credit expenses to export expenses when they have been closed" + "description": "Set corporate credit expenses to export expenses when they have been closed", + "icon": "pi-list-check" }}, {{ + "type": "action", "code": "set_customer_field_mapping_to_project" "title": "Map Customer field to Project", - "description": "Set Project field in Fyle mapped to 'Customers' field in QuickBooks Desktops." + "description": "Set Project field in Fyle mapped to 'Customers' field in QuickBooks Desktops.", + "icon": "pi-sitemap" }}, {{ + "type": "action", "code": "set_customer_field_mapping_to_cost_center", "title": "Map Customer field to Cost Center", - "description": "Set Cost Center field in Fyle mapped to 'Customers' field in QuickBooks Desktop." + "description": "Set Cost Center field in Fyle mapped to 'Customers' field in QuickBooks Desktop.", + "icon": "pi-sitemap" }}, {{ + "type": "action", "code" "set_class_field_mapping_to_project", "title": "Map Class field to Project", - "description": "Set Project field in Fyle mapped to 'Class' field in QuickBooks Desktop." + "description": "Set Project field in Fyle mapped to 'Class' field in QuickBooks Desktop.", + "icon": "pi-sitemap" }}, {{ + "type": "action", "code": "set_class_field_mapping_to_cost_center", "title": "Map Class field to Cost Center", - "description": "Set Cost Center field in Fyle mapped to 'Class' field in QuickBooks Desktop." + "description": "Set Cost Center field in Fyle mapped to 'Class' field in QuickBooks Desktop.", + "icon": "pi-sitemap" }} ] @@ -188,34 +240,44 @@ Navigations Map: "navigations": [ {{ + "type": "navigation", "code": "go_to_dashboard", "title": "Go to Dashboard", "description": "Navigate to the IIF file management section for import/export options.", - "url": "/dashboard" + "url": "/dashboard", + "icon": "pi-external-link" }}, {{ + "type": "navigation", "code": "go_to_settings", "title": "Go to Export Settings", "description": "Navigate to the export settings section to manage export configurations.", - "url": "/configuration/export_settings" + "url": "/configuration/export_settings", + "icon": "pi-external-link" }}, {{ + "type": "navigation", "code": "go_to_field_mappings", "title": "Go to Field Mappings", "description": "Navigate to the Field Mapping Settings Section to manage Field Mapping Settings.", - "url": "/configuration/field_mapping" + "url": "/configuration/field_mapping", + "icon": "pi-external-link" }}, {{ + "type": "navigation", "code": "go_to_advanced_settings", "title": "Go to Advanced Settings", "description": "Navigate to the advanced settings section to manage automatic export settings.", - "url": "/configuration/advanced_settings" + "url": "/configuration/advanced_settings", + "icon": "pi-external-link" }}, {{ + "type": "navigation", "code": "go_to_mappings", "title": "Go to Mappings Page", "description": "Navigate to the field mapping section to configure mappings.", - "url": "/mapping/corporate_card" + "url": "/mapping/corporate_card", + "icon": "pi-external-link" }} ] @@ -232,61 +294,79 @@ Output: {{ + "type": "help", "code": "learn_export", "title": "Learn more about IIF export", - "description": "How to export IIF File in QBD?." + "description": "How to export IIF File in QBD?.", + "code": "pi-info-circle" }} 2. User Query Inputs: ["Disable reimbursable expenses", "disable reimbursable export", "turn off reimbursable export", "stop exporting reimbursable expenses", "disable reimbursable expenses export", "disable export settings for reimbursable expenses", "deactivate reimbursable export", "disable reimbursable export settings", "turn off export for reimbursable expenses", "stop reimbursable export"] Output: {{ + "type": "help", "code": "disable_reimbursable_expenses_export", "title": "Disable reimbursable export settings", - "description": "Disable the option to export reimbursable expenses in Export Configuration in QBD." + "description": "Disable the option to export reimbursable expenses in Export Configuration in QBD.", + "code": "pi-info-circle" }} 3. User Query: ["How to manage IIF files?", "manage IIF files", "IIF file management", "how to filter IIF files", "filter IIF files by date", "manage files in QBD", "IIF file filters", "filter IIF data", "how to filter by date in QuickBooks Desktop", "date filters in IIF files", "QBD IIF file management", "file management in QuickBooks Desktop", "IIF file organization"] Output: {{ + "type": "help", "code": "date_filter_help", "title": "How to filter IIF files by date", - "description": "How to filter by date in QBD?" + "description": "How to filter by date in QBD?", + "code": "pi-info-circle" }} 4. User Query: "How to map fields?" {{ + "type": "help", "code": "configure_credit_card_mapping", "title": "How to configure credit card mapping", - "description": "how to set up field mappings for credit card transactions in QBD." + "description": "how to set up field mappings for credit card transactions in QBD.", + "code": "pi-info-circle" }} 5. User Query: "How to create field mappings?" {{ + "type": "help", "code": "field_mapping_help", "title": "How to create field mappings", - "description": "how to create new field mappings for import/export in QBD." + "description": "how to create new field mappings for import/export in QBD.", + "code": "pi-info-circle" }} 6. User Query: "How to set up automatic export?" {{ + "type": "help", "code": "automatic_export_help", "title": "How to set up automatic export", - "description": "how to configure automatic export settings for your data in QBD." + "description": "how to configure automatic export settings for your data in QBD.", + "code": "pi-info-circle" }} 7. User Query: "How to use memo field in export?" {{ + "type": "help", "code": "memo_field_help", "title": "How to use memo field in export", - "description": "how to properly set and use the memo field in data exports in QBD." + "description": "how to properly set and use the memo field in data exports in QBD.", + "code": "pi-info-circle" }} 8. User Query: "How to map fields?" {{ + "type": "help", "code": "map_fields_help", "title": "How to map fields", - "description": "how to map fields for accurate data handling and export in QBD." + "description": "how to map fields for accurate data handling and export in QBD.", + "code": "pi-info-circle" }} 9. User Query: "How to create new field mappings?" {{ + "type": "help", "code": "set_automatic_export", "title": "Set/Update automatic export settings", - "description": "how to create new field mappings for import/export in QBD." + "description": "how to create new field mappings for import/export in QBD.", + "code": "pi-info-circle" }} --------------------------- @@ -301,24 +381,29 @@ "suggestions": {{ "actions": [ {{ + "type": "action", "code": "trigger_export", "title": "Export IIF file", - "description": "Export the current data to an IIF file." + "description": "Export the current data to an IIF file.", + "icon": "pi-file-export" }} ], "navigations": [ {{ + "type": "navigation", "code": "go_to_dashboard", "title": "Go to Dashboard", "url": "/dashboard", - "description": "Navigate to the IIF file management section for import/export options." + "description": "Navigate to the IIF file management section for import/export options.", + "icon": "pi-external-link" }} ], "help": [ {{ "code": "learn_export", "title": "Learn more about IIF export", - "description": "How to export IIF files in QBD?" + "description": "How to export IIF files in QBD?", + "code": "pi-info-circle" }} ] }} @@ -331,59 +416,79 @@ "suggestions": {{ "actions": [ {{ + "type": "action", "code": "enable_reimbursable_expenses_export", "title": "Enable reimbursable export settings", - "description": "Enable the option to export reimbursable expenses in Export Configuration." + "description": "Enable the option to export reimbursable expenses in Export Configuration.", + ""icon": "pi-list-check" }}, {{ + "type": "action", "code": "disable_reimbursable_expenses_export", "title": "Disable reimbursable export settings", - "description": "Disable the option to export reimbursable expenses in Export Configuration." + "description": "Disable the option to export reimbursable expenses in Export Configuration.", + "icon": "pi-list-check" }}, {{ + "type": "action", "code": "set_reimbursable_expenses_export_module_bill", "title": "Select reimbursable export module as bill", - "description": "Choose Bill as the type of transaction in QuickBooks Desktop to export your Fyle expenses." + "description": "Choose Bill as the type of transaction in QuickBooks Desktop to export your Fyle expenses.", + "icon": "pi-list-check" }}, {{ + "type": "action", "code": "set_reimbursable_expenses_export_module_journal_entry", "title": "Select reimbursable export module as journal entry", - "description": "Choose Journal Entry as the type of transaction in QuickBooks Desktop to export your Fyle expenses." + "description": "Choose Journal Entry as the type of transaction in QuickBooks Desktop to export your Fyle expenses.", + "icon": "pi-list-check" }}, {{ + "type": "action", "code": "set_reimbursable_expenses_export_grouping_expense", "title": "Group reimbursable expenses export by expense", - "description": "Set grouping to expense, this grouping reflects how the expense entries are posted in QuickBooks Desktop." + "description": "Set grouping to expense, this grouping reflects how the expense entries are posted in QuickBooks Desktop.", + "icon": "pi-list-check" }}, {{ + "type": "action", "code": "set_reimbursable_expenses_export_grouping_expense_report", "title": "Group reimbursable expenses export by expense report", - "description": "Set grouping to expense_report, this grouping reflects how the expense entries are posted in QuickBooks Desktop." + "description": "Set grouping to expense_report, this grouping reflects how the expense entries are posted in QuickBooks Desktop.", + "icon": "pi-list-check" }}, {{ + "type": "action", "code": "set_reimbursable_expenses_export_export_state_processing", "title": "Set reimbursable expenses export state as processing", - "description": "You could choose to export expenses when they have been approved and are awaiting payment clearance." + "description": "You could choose to export expenses when they have been approved and are awaiting payment clearance.", + "icon": "pi-list-check" }}, {{ + "type": "action", "code": "set_reimbursable_expenses_export_export_state_paid", "title": "Set reimbursable expenses export state as paid", - "description": "You could choose to export expenses when they have been paid out." + "description": "You could choose to export expenses when they have been paid out.", + "icon": "pi-list-check" }} ], "help": [ {{ + "type": "help", "code": "learn_export_settings", "title": "Learn more about reimbursable expenses export settings", - "description": "How to enable or disable reimbursable export settings in QBD?" + "description": "How to enable or disable reimbursable export settings in QBD?", + "code": "pi-info-circle" }} ], "navigations": [ {{ + "type": "navigation", "code": "go_to_settings", "title": "Go to Export Settings", "description": "Navigate to the export settings section to manage export configurations.", - "url": "/configuration/export_settings" + "url": "/configuration/export_settings", + "icon": "pi-external-link" }} ] }} @@ -396,39 +501,51 @@ "suggestions": {{ "actions": [ {{ + "type": "action", "code": "set_customer_field_mapping_to_project", "title": "Map Customer field to Project", - "description": "Set Project field in Fyle mapped to 'Customers' field in QuickBooks Desktop." + "description": "Set Project field in Fyle mapped to 'Customers' field in QuickBooks Desktop.", + "icon": "pi-sitemap" }}, {{ + "type": "action", "code": "set_customer_field_mapping_to_cost_center", "title": "Map Customer field to Cost Center", - "description": "Set Cost Center field in Fyle mapped to 'Customers' field in QuickBooks Desktop." + "description": "Set Cost Center field in Fyle mapped to 'Customers' field in QuickBooks Desktop.", + "icon": "pi-sitemap" }}, {{ + "type": "action", "code": "set_class_field_mapping_to_project", "title": "Map Class field to Project", - "description": "Set Project field in Fyle mapped to 'Class' field in QuickBooks Desktop." + "description": "Set Project field in Fyle mapped to 'Class' field in QuickBooks Desktop.", + "icon": "pi-sitemap" }}, {{ + "type": "action", "code": "set_class_field_mapping_to_cost_center", "title": "Map Class field to Cost Center", - "description": "Set Cost Center field in Fyle mapped to 'Class' field in QuickBooks Desktop." + "description": "Set Cost Center field in Fyle mapped to 'Class' field in QuickBooks Desktop.", + "icon": "pi-sitemap" }} ], "navigations": [ {{ + "type": "navigation", "code": "go_to_field_mappings", "title": "Go to Field Mappings", "description": "Navigate to the Field Mapping Settings Section to manage Field Mapping Settings.", - "url": "/configuration/field_mapping" + "url": "/configuration/field_mapping", + "icon": "pi-external-link" }} ], "help": [ {{ + "type": "help", "code": "field_mapping_help", "title": "How to create field mappings", - "description": "How to create new field mappings for import/export in QBD?" + "description": "How to create new field mappings for import/export in QBD?", + "code": "pi-info-circle" }} ] }} @@ -441,24 +558,30 @@ "suggestions": {{ "actions" : [ {{ + "type": "action", "code": "set_automatic_export_settings", "title": "Set/Update automatic export settings", - "description": "Configure the automatic export settings for scheduled exports." + "description": "Configure the automatic export settings for scheduled exports.", + "icon": "pi-list-check" }} ], "navigations": [ {{ + "type": "navigation", "code": "go_to_advanced_settings", "title": "Go to Advanced Settings", "description": "Navigate to the advanced settings section to manage automatic export settings.", - "url": "/configuration/advanced_settings" + "url": "/configuration/advanced_settings", + "icon": "pi-external-link" }} ], "help": [ {{ + "type": "help", "code": "automatic_export_help", "title": "How to set up automatic export", - "description": "how to configure automatic export settings for your data in QBD?" + "description": "how to configure automatic export settings for your data in QBD?", + "code": "pi-info-circle" }} ] }} @@ -471,24 +594,30 @@ "suggestions": {{ "actions" : [ {{ + "type": "action", "code": "set_memo_field", "title": "Set/Update memo field for exports", - "description": "Configure the memo field for exported data to include relevant details." + "description": "Configure the memo field for exported data to include relevant details.", + "icon": "pi-list-check" }} ], "help": [ {{ + "type": "help", "code": "memo_field_help", "title": "How to use memo field in export", - "description": "how to properly set and use the memo field in data exports in QBD?" + "description": "how to properly set and use the memo field in data exports in QBD?", + "code": "pi-info-circle" }} ], "navigations": [ {{ + "type": "navigation", "code": "go_to_advanced_settings", "title": "Go to Advanced Settings", "description": "Navigate to the advanced settings section to configure memo field settings.", - "url": "/configuration/advanced_settings" + "url": "/configuration/advanced_settings", + "icon": "pi-external-link" }} ] }} @@ -500,30 +629,38 @@ "suggestions": {{ "actions" : [ {{ + "type": "action", "code": "map_fields", "title": "Map Fyle fields to QBD fields", - "description": "Configure the mapping of one field to another for iif export." + "description": "Configure the mapping of one field to another for iif export.", + "icon": "pi-sitemap" }} ], "help": [ {{ + "type": "help", "code": "map_fields_help", "title": "How to map fields", - "description": "how to map fields for accurate data handling and export in QBD?" + "description": "how to map fields for accurate data handling and export in QBD?", + "code": "pi-info-circle" }} ], "navigations": [ {{ + "type": "navigation", "code": "go_to_corporate_cards_mappings", "title": "Go to Corporate Card Mappings Page", "description": "Navigate to the corporate card field mapping section to configure mappings.", - url: "/mapping/corporate_card" + url: "/mapping/corporate_card", + "icon": "pi-external-link" }}, {{ + "type": "navigation", "code": "go_to_items_mappings", "title": "Go to Items Mappings Page", "description": "Navigate to the items field mapping section to configure mappings.", - url: "/mapping/item" + url: "/mapping/item", + "icon": "pi-external-link" }} ] }} From 88b97e4f5b2344da1855e6951891ea27aa835fd0 Mon Sep 17 00:00:00 2001 From: Ashutosh619-sudo Date: Fri, 13 Sep 2024 01:57:32 +0530 Subject: [PATCH 24/25] added suggestion based on page context --- .../prompts/suggestion_context_page_prompt.py | 175 ++++++++++++++++++ apps/spotlight/service.py | 9 + apps/spotlight/urls.py | 6 +- apps/spotlight/views.py | 12 +- 4 files changed, 199 insertions(+), 3 deletions(-) create mode 100644 apps/spotlight/prompts/suggestion_context_page_prompt.py diff --git a/apps/spotlight/prompts/suggestion_context_page_prompt.py b/apps/spotlight/prompts/suggestion_context_page_prompt.py new file mode 100644 index 0000000..953638e --- /dev/null +++ b/apps/spotlight/prompts/suggestion_context_page_prompt.py @@ -0,0 +1,175 @@ +SUGGESTION_PROMPT = """ + +Objectives: +You are a AI agent that suggests what actions and features +we provide for a specific page. You will get the user input at the end. + +Instructions: +These are the pages and their corresponding actions we provide, you will get the +URL as input and you have to reply the actions list: +Output should be in JSON format. + + +1. For /dashboard + Output: + {{ + "suggestions": {{ + "actions": [ + {{ + "code": "trigger_export", + "title": "Export IIF file", + "description": "Export the current data to an IIF file." + }} + ] + }} + }} + + +2. For /export_settings + Output: + {{ + "suggestions": {{ + "actions": [ + {{ + "code": "enable_reimbursable_expenses_export", + "title": "Enable reimbursable export settings", + "description": "Enable the option to export reimbursable expenses in Export Configuration." + }}, + {{ + "code": "disable_reimbursable_expenses_export", + "title": "Disable reimbursable export settings", + "description": "Disable the option to export reimbursable expenses in Export Configuration." + }}, + {{ + "code": "set_reimbursable_expenses_export_module_bill", + "title": "Select reimbursable export module as bill", + "description": "Choose Bill as the type of transaction in QuickBooks Desktop to export your Fyle expenses." + }}, + {{ + "code": "set_reimbursable_expenses_export_module_journal_entry", + "title": "Select reimbursable export module as journal entry", + "description": "Choose Journal Entry as the type of transaction in QuickBooks Desktop to export your Fyle expenses." + }}, + {{ + "code": "set_reimbursable_expenses_export_grouping_expense" + "title": "Group reimbursable expenses export by expense", + "description": "Set grouping to expense, this grouping reflects how the expense entries are posted in QuickBooks Desktop." + }}, + {{ + "code": "set_reimbursable_expenses_export_grouping_report", + "title": "Group reimbursable expenses export by report", + "description": "Set grouping to expense_report, this grouping reflects how the expense entries are posted in QuickBooks Desktop." + }}, + {{ + "code": "set_reimbursable_expenses_export_state_processing", + "title": "Set reimbursable expenses export state as processing", + "description": "You could choose to export expenses when they have been approved and are awaiting payment clearance." + }}, + {{ + "code": "set_reimbursable_expenses_export_state_paid", + "title": "Set reimbursable expenses export state as paid", + "description": "You could choose to export expenses when they have been paid out." + }}, + {{ + "code": "enable_corporate_card_expenses_export", + "title": "Enable option corporate card expenses export", + "description": "Enable the option to export of credit card expenses from Fyle to QuickBooks Desktop." + }}, + {{ + "code": "disable_corporate_card_expenses_export", + "title": "Disable reimbursable export settings", + "description": "Disable the option to export of credit card expenses from Fyle to QuickBooks Desktop." + }}, + {{ + "code": "set_corporate_credit_card_expenses_export_credit_card_purchase", + "title": "Set Credit Card Purchase transaction type to export", + "description": "Credit Card Purchase type of transaction in QuickBooks Desktop to be export as Fyle expenses." + }}, + {{ + "code": "set_corporate_credit_card_expenses_export_journal_entry", + "title": "Set Journal Entry transaction type to export", + "description": "Journal Entry type of transaction in QuickBooks Desktop to be export as Fyle expenses." + }}, + {{ + "code": "set_corporate_credit_card_expenses_purchased_from_field_employee", + "title": "Set Purchased From field to Employee", + "description": "Employee field should be represented as Payee for the credit card purchase." + }}, + {{ + "code": "set_corporate_credit_card_expenses_purchased_from_field_vendor", + "title": "Set Purchased From field to Vendor", + "description": "Vendor field should be represented as Payee for the credit card purchase." + }}, + {{ + "code": "set_corporate_credit_card_expenses_export_grouping_report", + "title": "Group corporate credit expenses export to report", + "description": "Group reports as the expense entries posted in QuickBooks Desktop." + }}, + {{ + "code": "set_corporate_credit_card_expenses_export_grouping_expense", + "title": "Group corporate credit expenses export to expenses", + "description": "Group expense as the expense entries posted in QuickBooks Desktop." + }}, + {{ + "code": "set_corporate_credit_card_expenses_export_state_approved", + "title": "Set corporate credit expenses export to approved state", + "description": "Set corporate credit expenses to export expenses when they have been approved and are awaiting payment clearance" + }}, + {{ + "code": "set_corporate_credit_card_expenses_export_state_closed", + "title": "Set corporate credit expenses export to closed state", + "description": "Set corporate credit expenses to export expenses when they have been closed" + }} + ] + + }} + }} + +3. /field_mappings + Output: + {{ + "suggestions": {{ + "actions": [ + {{ + "code": "set_customer_field_mapping_to_project" + "title": "Map Customer field to Project", + "description": "Set Project field in Fyle mapped to 'Customers' field in QuickBooks Desktops." + }}, + {{ + "code": "set_customer_field_mapping_to_cost_center", + "title": "Map Customer field to Cost Center", + "description": "Set Cost Center field in Fyle mapped to 'Customers' field in QuickBooks Desktop." + }}, + {{ + "code" "set_class_field_mapping_to_project", + "title": "Map Class field to Project", + "description": "Set Project field in Fyle mapped to 'Class' field in QuickBooks Desktop." + }}, + {{ + "code": "set_class_field_mapping_to_cost_center", + "title": "Map Class field to Cost Center", + "description": "Set Cost Center field in Fyle mapped to 'Class' field in QuickBooks Desktop." + }} + ] + }} +}} + + +----------------------------- +Important things to take care: +1. Match the user query and only reply the actions, nothing less nothing more. +2. Dont match the exact URL, it can be a bit different containing things in the beginning +or the end. +3. If the user query doesn't match any of the above provided URL please reply with empty suggestion like this: + +{{ + "suggestions": {{ + "actions": [] + }} +}} + +--------------------------- +User Query: {user_query} +--------------------------- + +""" diff --git a/apps/spotlight/service.py b/apps/spotlight/service.py index 6cf0528..88e5be5 100644 --- a/apps/spotlight/service.py +++ b/apps/spotlight/service.py @@ -9,6 +9,7 @@ from apps.workspaces.models import ExportSettings, FyleCredential from .prompts.support_genie import PROMPT as SUPPORT_GENIE_PROMPT from .prompts.spotlight_prompt import PROMPT as SPOTLIGHT_PROMPT +from .prompts.suggestion_context_page_prompt import SUGGESTION_PROMPT from . import llm @@ -58,6 +59,14 @@ def get_suggestions(cls, *, user_query: str) -> str: ) return llm.get_openai_response(system_prompt=formatted_prompt) +class SuggestionService: + @classmethod + def get_suggestions(cls, *, user_query: str) -> str: + formatted_prompt = SUGGESTION_PROMPT.format( + user_query=user_query + ) + + return llm.get_openai_response(system_prompt=formatted_prompt) class ActionService: diff --git a/apps/spotlight/urls.py b/apps/spotlight/urls.py index ff11aa1..6a5d266 100644 --- a/apps/spotlight/urls.py +++ b/apps/spotlight/urls.py @@ -14,7 +14,8 @@ """ from django.urls import path -from apps.spotlight.views import HelpQueryView, QueryView, RecentQueryView, ActionQueryView +from apps.spotlight.views import HelpQueryView, \ + QueryView, RecentQueryView, ActionQueryView, SuggestionForPage @@ -22,5 +23,6 @@ path('recent_queries/', RecentQueryView.as_view(), name='recent-queries'), path('query/', QueryView.as_view(), name='query'), path('help/', HelpQueryView.as_view(), name='help'), - path('action/', ActionQueryView.as_view(), name='action') + path('action/', ActionQueryView.as_view(), name='action'), + path('suggest_actions/', SuggestionForPage.as_view(), name='suggestion') ] diff --git a/apps/spotlight/views.py b/apps/spotlight/views.py index 87f5355..94d19ef 100644 --- a/apps/spotlight/views.py +++ b/apps/spotlight/views.py @@ -8,9 +8,11 @@ from apps.spotlight.models import Query from apps.spotlight.serializers import QuerySerializer -from .service import ActionService, HelpService, QueryService +from .service import ActionService, HelpService, QueryService, SuggestionService from apps.workspaces.models import FyleCredential from apps.fyle.helpers import get_access_token +from rest_framework.response import Response + code_action_map = { "trigger_export": 'http://localhost:8000/api/workspaces/2/trigger_export/' @@ -101,3 +103,11 @@ def post(self, request, *args, **kwargs): except Exception as e: print(e) return JsonResponse(data={"message": "Action failed"}, status=500) + +class SuggestionForPage(generics.CreateAPIView): + + def post(self, request, *args, **kwargs): + user_query = request.data['user_query'] + + support_response = SuggestionService.get_suggestions(user_query=user_query) + return JsonResponse(data={"message": support_response}) From 2dce0483581c97833d628061e67a41517c555016 Mon Sep 17 00:00:00 2001 From: Ashutosh619-sudo Date: Fri, 13 Sep 2024 03:47:35 +0530 Subject: [PATCH 25/25] Enable and disable export settings --- .../migrations/0002_copyexportsettings.py | 25 +++++ apps/spotlight/models.py | 9 ++ apps/spotlight/service.py | 103 ++++++++++++++++++ 3 files changed, 137 insertions(+) create mode 100644 apps/spotlight/migrations/0002_copyexportsettings.py diff --git a/apps/spotlight/migrations/0002_copyexportsettings.py b/apps/spotlight/migrations/0002_copyexportsettings.py new file mode 100644 index 0000000..d870c1f --- /dev/null +++ b/apps/spotlight/migrations/0002_copyexportsettings.py @@ -0,0 +1,25 @@ +# Generated by Django 3.1.14 on 2024-09-12 20:38 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('spotlight', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='CopyExportSettings', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('workspace_id', models.IntegerField(help_text='Workspace id of the organization')), + ('reimbursable_export_setting', models.JSONField(null=True)), + ('ccc_export_setting', models.JSONField(null=True)), + ], + options={ + 'db_table': 'copy_export_settings', + }, + ), + ] diff --git a/apps/spotlight/models.py b/apps/spotlight/models.py index 6186d34..e5f3b8c 100644 --- a/apps/spotlight/models.py +++ b/apps/spotlight/models.py @@ -21,3 +21,12 @@ class Query(models.Model): class Meta: db_table = 'queries' + +class CopyExportSettings(models.Model): + + workspace_id = models.IntegerField(help_text="Workspace id of the organization") + reimbursable_export_setting = models.JSONField(null=True) + ccc_export_setting = models.JSONField(null=True) + + class Meta: + db_table = 'copy_export_settings' diff --git a/apps/spotlight/service.py b/apps/spotlight/service.py index 88e5be5..f32ab31 100644 --- a/apps/spotlight/service.py +++ b/apps/spotlight/service.py @@ -6,6 +6,7 @@ import requests from apps.fyle.helpers import get_access_token +from apps.spotlight.models import CopyExportSettings from apps.workspaces.models import ExportSettings, FyleCredential from .prompts.support_genie import PROMPT as SUPPORT_GENIE_PROMPT from .prompts.spotlight_prompt import PROMPT as SPOTLIGHT_PROMPT @@ -88,6 +89,10 @@ def _get_action_function_from_code(cls, *, code: str) -> Callable: "set_corporate_credit_card_expenses_export_journal_entry": cls.set_cc_export_to_journal_entry, "set_corporate_credit_card_expenses_export_grouping_report": cls.set_cc_grouping_to_report, "set_corporate_credit_card_expenses_export_grouping_expense": cls.set_cc_grouping_to_expense, + "disable_reimbursable_expenses_export": cls.disable_reimbursable_expenses_export, + "enable_reimbursable_expenses_export": cls.enable_reimbursable_expenses_export, + "disable_corporate_card_expenses_export": cls.disable_corporate_card_expenses_export, + "enable_corporate_card_expenses_export": cls.enable_corporate_card_expenses_export } return code_to_function_map[code] @@ -324,6 +329,104 @@ def set_class_field_mapping_to_cost_center(cls, *, workspace_id: int): return ActionResponse(message="Field mapping updated successfully", is_success=True) return ActionResponse(message="Field mapping already exists", is_success=False) + @classmethod + def enable_reimbursable_expenses_export(cls, *, workspace_id: int): + fields_for_reimbursable = ['reimbursable_expenses_export_type', 'reimbursable_expense_state', 'reimbursable_expense_date', + 'reimbursable_expense_grouped_by', 'bank_account_name'] + + with transaction.atomic(): + export_settings = ExportSettings.objects.filter(workspace_id=workspace_id).first() + if export_settings: + if export_settings.reimbursable_expenses_export_type is None: + copied_export_settings = CopyExportSettings.objects.filter(workspace_id=workspace_id).first() + if copied_export_settings: + for field in fields_for_reimbursable: + setattr(export_settings, field, copied_export_settings.reimbursable_export_setting[field]) + + export_settings.save() + return ActionResponse(message='Successfully enabled reimbursable expense', is_success=True) + else: + return ActionResponse(message='Reimbursable Expense is already enabled', is_success=True) + + return ActionResponse(message="Export settings doesn't exists", is_success=False) + + @classmethod + def disable_reimbursable_expenses_export(cls, *, workspace_id: int): + fields_for_reimbursable = ['reimbursable_expenses_export_type', 'reimbursable_expense_state', 'reimbursable_expense_date', + 'reimbursable_expense_grouped_by', 'bank_account_name'] + with transaction.atomic(): + export_settings = ExportSettings.objects.filter(workspace_id=workspace_id).first() + if export_settings: + if export_settings.reimbursable_expenses_export_type is not None: + copied_export_settings, _ = CopyExportSettings.objects.get_or_create(workspace_id=workspace_id, + defaults={'reimbursable_export_setting': {}, 'ccc_export_setting': {}}) + reimbursable_export_setting = copied_export_settings.reimbursable_export_setting or {} + + for field in fields_for_reimbursable: + reimbursable_export_setting[field] = getattr(export_settings, field, None) + setattr(export_settings, field, None) + + copied_export_settings.reimbursable_export_setting = reimbursable_export_setting + + export_settings.save() + copied_export_settings.save() + + return ActionResponse(message='Reimbursable Expense successfully disabled!', is_success=True) + + else: + return ActionResponse(message='Reimbursable Expense is already disabled', is_success=True) + + return ActionResponse(message="Export settings doesn't exists", is_success=False) + + @classmethod + def enable_corporate_card_expenses_export(cls, *, workspace_id: int): + fields_for_ccc = ['credit_card_expense_export_type', 'credit_card_expense_state', 'credit_card_entity_name_preference', + 'credit_card_account_name', 'credit_card_expense_grouped_by', 'credit_card_expense_date'] + + with transaction.atomic(): + export_settings = ExportSettings.objects.filter(workspace_id=workspace_id).first() + if export_settings: + if export_settings.credit_card_expense_export_type is None: + copied_export_settings = CopyExportSettings.objects.filter(workspace_id=workspace_id).first() + if copied_export_settings: + for field in fields_for_ccc: + setattr(export_settings, field, copied_export_settings.ccc_export_setting[field]) + + export_settings.save() + return ActionResponse(message='Successfully enabled Corporate expense', is_success=True) + else: + return ActionResponse(message='Corporate Expense is already enabled', is_success=True) + + return ActionResponse(message="Export settings doesn't exists", is_success=False) + + @classmethod + def disable_corporate_card_expenses_export(cls, *, workspace_id: int): + fields_for_ccc = ['credit_card_expense_export_type', 'credit_card_expense_state', 'credit_card_entity_name_preference', + 'credit_card_account_name', 'credit_card_expense_grouped_by', 'credit_card_expense_date'] + with transaction.atomic(): + export_settings = ExportSettings.objects.filter(workspace_id=workspace_id).first() + if export_settings: + if export_settings.credit_card_expense_export_type is not None: + copied_export_settings, _ = CopyExportSettings.objects.get_or_create(workspace_id=workspace_id, + defaults={'reimbursable_export_setting': {}, 'ccc_export_setting': {}}) + ccc_export_setting = copied_export_settings.ccc_export_setting or {} + + for field in fields_for_ccc: + ccc_export_setting[field] = getattr(export_settings, field, None) + setattr(export_settings, field, None) + + copied_export_settings.ccc_export_setting = ccc_export_setting + + export_settings.save() + copied_export_settings.save() + + return ActionResponse(message='Corporate Expense successfully disabled!', is_success=True) + + else: + return ActionResponse(message='Corporate Expense is already disabled', is_success=True) + + return ActionResponse(message="Export settings doesn't exists", is_success=False) + @classmethod def action(cls, *, code: str, workspace_id: str): action_function = cls._get_action_function_from_code(code=code)