-
Notifications
You must be signed in to change notification settings - Fork 84
odoo multiple branch option #2320
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -136,6 +136,27 @@ def save_client_details( | |||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||
| return record | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| @staticmethod | ||||||||||||||||||||||||||||||||||||||
| def save_branch_details(bot: str, branch_name: str, company_id: int, user: str, pos_type: POSType = POSType.odoo.value): | ||||||||||||||||||||||||||||||||||||||
| record = POSClientDetails.objects(bot=bot, pos_type=POSType.odoo.value).first() | ||||||||||||||||||||||||||||||||||||||
| if not record: | ||||||||||||||||||||||||||||||||||||||
| raise AppException("No POS client configuration found for this bot.") | ||||||||||||||||||||||||||||||||||||||
| data = record.to_mongo().to_dict() | ||||||||||||||||||||||||||||||||||||||
| client_name = data["client_name"] | ||||||||||||||||||||||||||||||||||||||
| branch_details = { | ||||||||||||||||||||||||||||||||||||||
| "branch_name": branch_name.strip(), | ||||||||||||||||||||||||||||||||||||||
| "company_id": company_id | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| record = POSClientDetails.objects( | ||||||||||||||||||||||||||||||||||||||
| bot=bot, | ||||||||||||||||||||||||||||||||||||||
| client_name=client_name | ||||||||||||||||||||||||||||||||||||||
| ).update_one( | ||||||||||||||||||||||||||||||||||||||
| push__branches=branch_details | ||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| return record | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| @staticmethod | ||||||||||||||||||||||||||||||||||||||
| def get_client_details(bot: str): | ||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||
|
|
@@ -494,7 +515,7 @@ def jsonrpc_get_uid(self, session_id: str) -> int: | |||||||||||||||||||||||||||||||||||||
| kwargs={"limit": 1} | ||||||||||||||||||||||||||||||||||||||
| )[0] | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| def create_pos_order(self, session_id: str, products: list, partner_id: int = None): | ||||||||||||||||||||||||||||||||||||||
| def create_pos_order(self, session_id: str, products: list, partner_id: int = None, company_id: int = 1): | ||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||
| Create POS order using JSON-RPC (create_from_ui) | ||||||||||||||||||||||||||||||||||||||
| with check for available_in_pos for every product. | ||||||||||||||||||||||||||||||||||||||
|
|
@@ -579,15 +600,20 @@ def create_pos_order(self, session_id: str, products: list, partner_id: int = No | |||||||||||||||||||||||||||||||||||||
| model="pos.config", | ||||||||||||||||||||||||||||||||||||||
| method="search_read", | ||||||||||||||||||||||||||||||||||||||
| args=[[["active", "=", True]]], | ||||||||||||||||||||||||||||||||||||||
| kwargs={"limit": 1} | ||||||||||||||||||||||||||||||||||||||
| kwargs={ | ||||||||||||||||||||||||||||||||||||||
| "fields": ["id", "company_id"] | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| if not pos_configs: | ||||||||||||||||||||||||||||||||||||||
| raise AppException("No POS Config found") | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| config = pos_configs[0] | ||||||||||||||||||||||||||||||||||||||
| config_id = config["id"] | ||||||||||||||||||||||||||||||||||||||
| company_id = config["company_id"][0] if config.get("company_id") else False | ||||||||||||||||||||||||||||||||||||||
| config_id = None | ||||||||||||||||||||||||||||||||||||||
| for config in pos_configs: | ||||||||||||||||||||||||||||||||||||||
| comp_id = config["company_id"][0] if config.get("company_id") else False | ||||||||||||||||||||||||||||||||||||||
| if company_id == comp_id: | ||||||||||||||||||||||||||||||||||||||
| config_id = config["id"] | ||||||||||||||||||||||||||||||||||||||
| break | ||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+611
to
+616
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Handle the case when no matching POS config is found for the If no config matches the provided Proposed fix config_id = None
for config in pos_configs:
comp_id = config["company_id"][0] if config.get("company_id") else False
if company_id == comp_id:
config_id = config["id"]
break
+
+ if config_id is None:
+ raise HTTPException(
+ status_code=404,
+ detail=f"No POS config found for company_id {company_id}"
+ )📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| open_session = self.jsonrpc_call( | ||||||||||||||||||||||||||||||||||||||
| session_id=session_id, | ||||||||||||||||||||||||||||||||||||||
|
|
@@ -602,9 +628,11 @@ def create_pos_order(self, session_id: str, products: list, partner_id: int = No | |||||||||||||||||||||||||||||||||||||
| kwargs={"limit": 1} | ||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| payment_method_ids=[] | ||||||||||||||||||||||||||||||||||||||
| if open_session: | ||||||||||||||||||||||||||||||||||||||
| session_id_odoo = open_session[0]["id"] | ||||||||||||||||||||||||||||||||||||||
| sequence_number = open_session[0].get("sequence_number", 1) | ||||||||||||||||||||||||||||||||||||||
| payment_method_ids = open_session[0].get("payment_method_ids", []) | ||||||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||||||
| session_id_odoo = self.jsonrpc_call( | ||||||||||||||||||||||||||||||||||||||
| session_id=session_id, | ||||||||||||||||||||||||||||||||||||||
|
|
@@ -622,27 +650,19 @@ def create_pos_order(self, session_id: str, products: list, partner_id: int = No | |||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| sequence_number = 1 | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| pay_method = self.jsonrpc_call( | ||||||||||||||||||||||||||||||||||||||
| session_id=session_id, | ||||||||||||||||||||||||||||||||||||||
| model="pos.payment.method", | ||||||||||||||||||||||||||||||||||||||
| method="search_read", | ||||||||||||||||||||||||||||||||||||||
| args=[[["is_cash_count", "=", True]]], | ||||||||||||||||||||||||||||||||||||||
| kwargs={"limit": 1} | ||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| if not pay_method: | ||||||||||||||||||||||||||||||||||||||
| pay_method = self.jsonrpc_call( | ||||||||||||||||||||||||||||||||||||||
| if not payment_method_ids: | ||||||||||||||||||||||||||||||||||||||
| payment_method_ids = self.jsonrpc_call( | ||||||||||||||||||||||||||||||||||||||
| session_id=session_id, | ||||||||||||||||||||||||||||||||||||||
| model="pos.payment.method", | ||||||||||||||||||||||||||||||||||||||
| method="search_read", | ||||||||||||||||||||||||||||||||||||||
| args=[[[]]], | ||||||||||||||||||||||||||||||||||||||
| kwargs={"limit": 1} | ||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| if not pay_method: | ||||||||||||||||||||||||||||||||||||||
| if not payment_method_ids: | ||||||||||||||||||||||||||||||||||||||
| raise HTTPException(status_code=400, detail="No POS payment methods found") | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| payment_method_id = pay_method[0]["id"] | ||||||||||||||||||||||||||||||||||||||
| payment_method_id = payment_method_ids[0] | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| order_data = { | ||||||||||||||||||||||||||||||||||||||
| "name": f"POS/{int(time.time())}", | ||||||||||||||||||||||||||||||||||||||
|
|
@@ -680,6 +700,74 @@ def create_pos_order(self, session_id: str, products: list, partner_id: int = No | |||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| return {"order_id": order_id, "status": "created"} | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| def create_branch(self, session_id: str, branch_name: str, street: str, city: str, state: str, bot: str, user: str): | ||||||||||||||||||||||||||||||||||||||
| INDIA_STATE_MAP = { | ||||||||||||||||||||||||||||||||||||||
| "Andaman and Nicobar": 577, | ||||||||||||||||||||||||||||||||||||||
| "Andhra Pradesh": 578, | ||||||||||||||||||||||||||||||||||||||
| "Arunachal Pradesh": 579, | ||||||||||||||||||||||||||||||||||||||
| "Assam": 580, | ||||||||||||||||||||||||||||||||||||||
| "Bihar": 581, | ||||||||||||||||||||||||||||||||||||||
| "Chattisgarh": 583, | ||||||||||||||||||||||||||||||||||||||
| "Chandigarh": 582, | ||||||||||||||||||||||||||||||||||||||
| "Daman and Diu": 585, | ||||||||||||||||||||||||||||||||||||||
| "Delhi": 586, | ||||||||||||||||||||||||||||||||||||||
| "Dadra and Nagar Haveli": 584, | ||||||||||||||||||||||||||||||||||||||
| "Goa": 587, | ||||||||||||||||||||||||||||||||||||||
| "Gujarat": 588, | ||||||||||||||||||||||||||||||||||||||
| "Himachal Pradesh": 590, | ||||||||||||||||||||||||||||||||||||||
| "Haryana": 589, | ||||||||||||||||||||||||||||||||||||||
| "Jharkhand": 592, | ||||||||||||||||||||||||||||||||||||||
| "Jammu and Kashmir": 591, | ||||||||||||||||||||||||||||||||||||||
| "Karnataka": 593, | ||||||||||||||||||||||||||||||||||||||
| "Kerala": 594, | ||||||||||||||||||||||||||||||||||||||
| "Lakshadweep": 595, | ||||||||||||||||||||||||||||||||||||||
| "Maharashtra": 597, | ||||||||||||||||||||||||||||||||||||||
| "Meghalaya": 599, | ||||||||||||||||||||||||||||||||||||||
| "Manipur": 598, | ||||||||||||||||||||||||||||||||||||||
| "Madhya Pradesh": 596, | ||||||||||||||||||||||||||||||||||||||
| "Mizoram": 600, | ||||||||||||||||||||||||||||||||||||||
| "Nagaland": 601, | ||||||||||||||||||||||||||||||||||||||
| "Odisha": 602, | ||||||||||||||||||||||||||||||||||||||
| "Punjab": 604, | ||||||||||||||||||||||||||||||||||||||
| "Puducherry": 603, | ||||||||||||||||||||||||||||||||||||||
| "Rajasthan": 605, | ||||||||||||||||||||||||||||||||||||||
| "Sikkim": 606, | ||||||||||||||||||||||||||||||||||||||
| "Tamil Nadu": 607, | ||||||||||||||||||||||||||||||||||||||
| "Tripura": 609, | ||||||||||||||||||||||||||||||||||||||
| "Telangana": 608, | ||||||||||||||||||||||||||||||||||||||
| "Uttarakhand": 611, | ||||||||||||||||||||||||||||||||||||||
| "Uttar Pradesh": 610, | ||||||||||||||||||||||||||||||||||||||
| "West Bengal": 612 | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
| try: | ||||||||||||||||||||||||||||||||||||||
| state_id = INDIA_STATE_MAP[state] | ||||||||||||||||||||||||||||||||||||||
| except KeyError: | ||||||||||||||||||||||||||||||||||||||
| raise HTTPException(status_code=400, detail=f"Invalid state: {state}") | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| branch_data = self.jsonrpc_call( | ||||||||||||||||||||||||||||||||||||||
| session_id=session_id, | ||||||||||||||||||||||||||||||||||||||
| model="res.company", | ||||||||||||||||||||||||||||||||||||||
| method="create", | ||||||||||||||||||||||||||||||||||||||
| args= [ | ||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||
| "name": branch_name, | ||||||||||||||||||||||||||||||||||||||
| "parent_id": 1, | ||||||||||||||||||||||||||||||||||||||
| "currency_id": 1, | ||||||||||||||||||||||||||||||||||||||
| "country_id": 104, | ||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+754
to
+756
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: # First, examine the specific file and lines in question
cd /repo && cat -n kairon/shared/pos/processor.py | sed -n '750,760p'Repository: digiteinfotech/kairon Length of output: 120 🏁 Script executed: # Search for usage patterns of these IDs across the codebase
rg -n "parent_id|currency_id|country_id" --type py -B2 -A2Repository: digiteinfotech/kairon Length of output: 2602 🏁 Script executed: # Check if there's any configuration file or module for Odoo settings
fd -e py -e json -e yaml -e toml -e conf | xargs rg -l "parent_id|currency_id|country_id|odoo.*config" 2>/dev/null | head -20Repository: digiteinfotech/kairon Length of output: 489 🏁 Script executed: cat -n kairon/shared/pos/processor.py | sed -n '740,770p'Repository: digiteinfotech/kairon Length of output: 1290 🏁 Script executed: # Search for the function containing these lines and understand the context
rg -n "def.*\(" kairon/shared/pos/processor.py | head -20Repository: digiteinfotech/kairon Length of output: 1651 🏁 Script executed: # Check if there's any Odoo configuration or settings file
rg -n "odoo|currency_id|country_id" kairon/shared/pos/processor.py -B5 -A5Repository: digiteinfotech/kairon Length of output: 4795 🏁 Script executed: # Look for configuration files that might contain these ID mappings
fd -type f \( -name "*.py" -o -name "*.json" -o -name "*.yaml" -o -name "*.toml" -o -name "*.conf" \) | xargs rg -l "config|setting" | grep -E "(config|setting|constant|env)" | head -10Repository: digiteinfotech/kairon Length of output: 852 🏁 Script executed: # Look for configuration files and environment setup
rg -n "parent_id|currency_id|country_id|odoo.*config" kairon/ --type py | grep -v test | grep -v ".pyc"Repository: digiteinfotech/kairon Length of output: 478 🏁 Script executed: # Check the Utility.environment setup to understand config structure
rg -n "environment\[.*pos" kairon/ --type py | head -20Repository: digiteinfotech/kairon Length of output: 480 🏁 Script executed: # Look for any dynamic ID resolution or query patterns for these entities
rg -n "search.*parent|search.*currency|search.*country" kairon/shared/pos/ --type py -B2 -A2Repository: digiteinfotech/kairon Length of output: 47 🏁 Script executed: # Check if there are similar hardcoded patterns elsewhere in the codebase
rg -n "jsonrpc_call.*create" kairon/shared/pos/processor.py --type py -B3 -A3Repository: digiteinfotech/kairon Length of output: 458 🏁 Script executed: # Check if there's any documentation or comments about India-specificity
rg -n "india|104|country_id" kairon/shared/pos/processor.py -B5 -A5 | head -50Repository: digiteinfotech/kairon Length of output: 467 🏁 Script executed: # Check the create_branch function signature and docstring
sed -n '703,720p' kairon/shared/pos/processor.pyRepository: digiteinfotech/kairon Length of output: 729 🏁 Script executed: # Search for any test files that might show intended usage
rg -n "create_branch|country_id.*104" tests/ --type pyRepository: digiteinfotech/kairon Length of output: 1195 🏁 Script executed: # Check Utility.environment structure to see how config is loaded
rg -n "class Utility" kairon/shared/utils.py -A 30 | head -50Repository: digiteinfotech/kairon Length of output: 1210 🏁 Script executed: # Look for environment configuration files
fd -type f -name "*.yaml" -o -name "*.yml" -o -name "*.json" | xargs rg -l "pos.*odoo\|country\|currency" 2>/dev/null | head -10Repository: digiteinfotech/kairon Length of output: 235 🏁 Script executed: # Check if the IDs are mentioned in documentation or readme
find . -name "README*" -o -name "*.md" | xargs rg -l "104\|country_id\|create_branch" 2>/dev/nullRepository: digiteinfotech/kairon Length of output: 49 🏁 Script executed: # Look at the full create_branch function to understand the context better
sed -n '703,770p' kairon/shared/pos/processor.pyRepository: digiteinfotech/kairon Length of output: 2306 🏁 Script executed: # Check if there's any configuration that might override these values
rg -n "parent_id.*=|currency_id.*=|country_id.*=" kairon/ --type py | grep -v test | grep -v ".pyc"Repository: digiteinfotech/kairon Length of output: 183 🏁 Script executed: # Look for Odoo documentation or comments about these standard IDs
rg -n "INR|india|odoo" kairon/shared/pos/processor.py -iRepository: digiteinfotech/kairon Length of output: 1795 Make country_id, currency_id, and parent_id configurable instead of hardcoded. The hardcoded values 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||
| "state_id": state_id, | ||||||||||||||||||||||||||||||||||||||
| "street": street, | ||||||||||||||||||||||||||||||||||||||
| "city": city, | ||||||||||||||||||||||||||||||||||||||
| "active": True | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
| ], | ||||||||||||||||||||||||||||||||||||||
| kwargs= {} | ||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||
| if not branch_data: | ||||||||||||||||||||||||||||||||||||||
| raise HTTPException(status_code=404, detail="Error in creating branch") | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| POSProcessor.save_branch_details(bot, branch_name, branch_data, user) | ||||||||||||||||||||||||||||||||||||||
| return {"branch_id": branch_data, "status": "created"} | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| def accept_pos_order(self, session_id: str, order_id: int) -> Dict[str, Any]: | ||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||
| Accept a POS order: tries to create payment and invoice it. | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix type hint for optional parameter.
The
partner_idparameter should be explicitly typed as optional per PEP 484.🔧 Suggested fix
🧰 Tools
🪛 Ruff (0.14.10)
497-497: PEP 484 prohibits implicit
OptionalConvert to
T | None(RUF013)
🤖 Prompt for AI Agents