convexity-sdk 0.21.0.dev332__tar.gz → 0.21.0.dev336__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/PKG-INFO +1 -1
  2. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/resources/crm.py +94 -0
  3. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/resources/sales.py +6 -0
  4. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/resources/warehouses.py +84 -0
  5. convexity_sdk-0.21.0.dev336/samples/crm/004_manage_sales_reps.py +55 -0
  6. convexity_sdk-0.21.0.dev336/samples/inventory/009_list_location_items.py +38 -0
  7. convexity_sdk-0.21.0.dev336/samples/inventory/010_list_item_warehouse_locations.py +38 -0
  8. convexity_sdk-0.21.0.dev336/samples/inventory/011_assign_item_location.py +20 -0
  9. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/.gitignore +0 -0
  10. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/README.md +0 -0
  11. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/__init__.py +0 -0
  12. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/client.py +0 -0
  13. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/config.py +0 -0
  14. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/exceptions.py +0 -0
  15. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/http.py +0 -0
  16. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/models/__init__.py +0 -0
  17. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/resources/__init__.py +0 -0
  18. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/resources/address_book.py +0 -0
  19. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/resources/analytics.py +0 -0
  20. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/resources/api_keys.py +0 -0
  21. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/resources/attributes.py +0 -0
  22. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/resources/categories.py +0 -0
  23. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/resources/classification.py +0 -0
  24. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/resources/connections.py +0 -0
  25. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/resources/cost_lists.py +0 -0
  26. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/resources/dashboards.py +0 -0
  27. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/resources/datasets.py +0 -0
  28. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/resources/email.py +0 -0
  29. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/resources/environments.py +0 -0
  30. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/resources/erp_config.py +0 -0
  31. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/resources/imports.py +0 -0
  32. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/resources/inventory.py +0 -0
  33. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/resources/issues.py +0 -0
  34. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/resources/olap.py +0 -0
  35. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/resources/organization_invitations.py +0 -0
  36. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/resources/organizations.py +0 -0
  37. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/resources/pricing.py +0 -0
  38. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/resources/projects.py +0 -0
  39. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/resources/purchasing.py +0 -0
  40. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/resources/rbac.py +0 -0
  41. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/resources/replenishment.py +0 -0
  42. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/resources/runs.py +0 -0
  43. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/resources/sales_channels.py +0 -0
  44. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/resources/tasks.py +0 -0
  45. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/resources/templates.py +0 -0
  46. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/resources/usage.py +0 -0
  47. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/resources/worker_tasks.py +0 -0
  48. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/convexity_sdk/resources/workspace.py +0 -0
  49. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/pyproject.toml +0 -0
  50. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/.env.example +0 -0
  51. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/README.md +0 -0
  52. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/cancel_refresh_task.py +0 -0
  53. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/compare_api_key_scopes.py +0 -0
  54. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/create_csv_datasets.py +0 -0
  55. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/create_dashboards.py +0 -0
  56. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/create_databricks_connections.py +0 -0
  57. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/create_datasets.py +0 -0
  58. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/create_forecast_task.py +0 -0
  59. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/create_org_and_project.py +0 -0
  60. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/create_single_project_api_key.py +0 -0
  61. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/crm/001_check_crm_enabled.py +0 -0
  62. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/crm/002_enable_crm.py +0 -0
  63. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/crm/003_manage_customers.py +0 -0
  64. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/crm/004_disable_crm.py +0 -0
  65. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/getting_started.py +0 -0
  66. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/inventory/001_check_inventory_enabled.py +0 -0
  67. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/inventory/002_enable_inventory.py +0 -0
  68. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/inventory/003_manage_inventory_items.py +0 -0
  69. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/inventory/004_manage_inventory_stock.py +0 -0
  70. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/inventory/005_disable_inventory.py +0 -0
  71. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/inventory/006_manage_categories.py +0 -0
  72. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/inventory/007_manage_inventory_config.py +0 -0
  73. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/inventory/008_manage_cost_lists.py +0 -0
  74. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/list_orgs_and_projects.py +0 -0
  75. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/manage_environments.py +0 -0
  76. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/manage_issues.py +0 -0
  77. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/project_usage.py +0 -0
  78. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/purchasing/001_check_purchasing_enabled.py +0 -0
  79. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/purchasing/002_enable_purchasing.py +0 -0
  80. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/purchasing/003_manage_vendors.py +0 -0
  81. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/purchasing/004_manage_purchase_orders.py +0 -0
  82. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/purchasing/005_disable_purchasing.py +0 -0
  83. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/query_olap.py +0 -0
  84. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/quickbook/001_check_quickbook_connection.py +0 -0
  85. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/quickbook/002_create_quickbook_datasets.py +0 -0
  86. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/rbac/001_manage_roles.py +0 -0
  87. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/rbac/002_manage_assignments.py +0 -0
  88. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/rbac/003_verify_rbac_access.py +0 -0
  89. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/sales/001_check_sales_enabled.py +0 -0
  90. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/sales/002_enable_sales.py +0 -0
  91. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/sales/003_manage_sales_invoices.py +0 -0
  92. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/sales/004_manage_sales_invoice_lifecycle.py +0 -0
  93. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/sales/005_manage_sales_orders.py +0 -0
  94. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/sales/006_disable_sales.py +0 -0
  95. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/share_dashboard.py +0 -0
  96. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/shopify/001_check_shopify_connection.py +0 -0
  97. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/shopify/002_create_shopify_datasets.py +0 -0
  98. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/uci/001_setup.py +0 -0
  99. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/uci/002_seed_inventory_from_uci.py +0 -0
  100. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/uci/003_seed_sales_from_uci.py +0 -0
  101. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/uci/004_seed_purchasing_from_uci.py +0 -0
  102. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/uci/005_run_pipelines.py +0 -0
  103. {convexity_sdk-0.21.0.dev332 → convexity_sdk-0.21.0.dev336}/samples/workspace_files.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: convexity-sdk
3
- Version: 0.21.0.dev332
3
+ Version: 0.21.0.dev336
4
4
  Summary: Convexity Python SDK - programmatic access to the Convexity platform
5
5
  Requires-Python: >=3.12
6
6
  Requires-Dist: convexity-api-client
@@ -7,17 +7,26 @@ from typing import Any, TypeVar, cast
7
7
  from convexity_api_client import AuthenticatedClient, Client
8
8
  from convexity_api_client.api.v1 import crm_bulk_upsert_customers as _bulk_upsert_customers
9
9
  from convexity_api_client.api.v1 import crm_create_customer as _create_customer
10
+ from convexity_api_client.api.v1 import crm_create_sales_rep as _create_sales_rep
10
11
  from convexity_api_client.api.v1 import crm_delete_customer as _delete_customer
12
+ from convexity_api_client.api.v1 import crm_delete_sales_rep as _delete_sales_rep
11
13
  from convexity_api_client.api.v1 import crm_get_customer as _get_customer
14
+ from convexity_api_client.api.v1 import crm_get_sales_rep as _get_sales_rep
12
15
  from convexity_api_client.api.v1 import crm_list_customers as _list_customers
16
+ from convexity_api_client.api.v1 import crm_list_sales_reps as _list_sales_reps
13
17
  from convexity_api_client.api.v1 import crm_update_customer as _update_customer
18
+ from convexity_api_client.api.v1 import crm_update_sales_rep as _update_sales_rep
14
19
  from convexity_api_client.models.bulk_upsert_customer_payload import BulkUpsertCustomerPayload
15
20
  from convexity_api_client.models.bulk_upsert_customers_request import BulkUpsertCustomersRequest
16
21
  from convexity_api_client.models.bulk_upsert_customers_response import BulkUpsertCustomersResponse
17
22
  from convexity_api_client.models.create_customer_request import CreateCustomerRequest
23
+ from convexity_api_client.models.create_sales_rep_request import CreateSalesRepRequest
18
24
  from convexity_api_client.models.customer_response import CustomerResponse
19
25
  from convexity_api_client.models.list_customers_response import ListCustomersResponse
26
+ from convexity_api_client.models.list_sales_reps_response import ListSalesRepsResponse
27
+ from convexity_api_client.models.sales_rep_response import SalesRepResponse
20
28
  from convexity_api_client.models.update_customer_request import UpdateCustomerRequest
29
+ from convexity_api_client.models.update_sales_rep_request import UpdateSalesRepRequest
21
30
  from convexity_api_client.types import UNSET, Unset
22
31
 
23
32
  ResponseT = TypeVar("ResponseT")
@@ -55,6 +64,7 @@ class CRM:
55
64
  default_shipping_address_entry_id: str | None = None,
56
65
  currency: str = "USD",
57
66
  payment_term_id: str | None = None,
67
+ sales_rep_id: str | None = None,
58
68
  credit_limit: float | None = None,
59
69
  ext_data: dict[str, Any] | None = None,
60
70
  ) -> CustomerResponse:
@@ -68,6 +78,7 @@ class CRM:
68
78
  default_shipping_address_entry_id=_optional(default_shipping_address_entry_id),
69
79
  currency=currency,
70
80
  payment_term_id=_optional(payment_term_id),
81
+ sales_rep_id=_optional(sales_rep_id),
71
82
  credit_limit=_optional(credit_limit),
72
83
  ext_data=cast(Any, _optional(ext_data)),
73
84
  )
@@ -126,6 +137,7 @@ class CRM:
126
137
  default_shipping_address_entry_id: str | None = None,
127
138
  currency: str | None = None,
128
139
  payment_term_id: str | None = None,
140
+ sales_rep_id: str | None | Unset = UNSET,
129
141
  credit_limit: float | None = None,
130
142
  is_active: bool | None = None,
131
143
  ext_data: dict[str, Any] | None = None,
@@ -139,6 +151,7 @@ class CRM:
139
151
  default_shipping_address_entry_id=_optional(default_shipping_address_entry_id),
140
152
  currency=_optional(currency),
141
153
  payment_term_id=_optional(payment_term_id),
154
+ sales_rep_id=sales_rep_id,
142
155
  credit_limit=_optional(credit_limit),
143
156
  is_active=_optional(is_active),
144
157
  ext_data=cast(Any, _optional(ext_data)),
@@ -150,3 +163,84 @@ class CRM:
150
163
  """Delete a CRM customer/account."""
151
164
  result = _delete_customer.sync(customer_id, client=self._client, project_id=project_id)
152
165
  return _expect_response(result, CustomerResponse, "deleting customer")
166
+
167
+ def create_sales_rep(
168
+ self,
169
+ *,
170
+ project_id: str,
171
+ code: str,
172
+ name: str | None = None,
173
+ email: str | None = None,
174
+ user_id: str | None = None,
175
+ default_commission_rate: float | str | None = None,
176
+ ext_data: dict[str, Any] | None = None,
177
+ ) -> SalesRepResponse:
178
+ """Create a sales rep, optionally linked to an organization member."""
179
+ body = CreateSalesRepRequest(
180
+ code=code,
181
+ name=_optional(name),
182
+ email=_optional(email),
183
+ user_id=_optional(user_id),
184
+ default_commission_rate=_optional(default_commission_rate),
185
+ ext_data=cast(Any, _optional(ext_data)),
186
+ )
187
+ result = _create_sales_rep.sync(client=self._client, body=body, project_id=project_id)
188
+ return _expect_response(result, SalesRepResponse, "creating sales rep")
189
+
190
+ def list_sales_reps(
191
+ self,
192
+ *,
193
+ project_id: str,
194
+ search: str | None = None,
195
+ is_active: bool | None = None,
196
+ limit: int = 50,
197
+ offset: int = 0,
198
+ ) -> ListSalesRepsResponse:
199
+ """List sales reps for a project."""
200
+ result = _list_sales_reps.sync(
201
+ client=self._client,
202
+ search=_optional(search),
203
+ is_active=_optional(is_active),
204
+ limit=limit,
205
+ offset=offset,
206
+ project_id=project_id,
207
+ )
208
+ if isinstance(result, ListSalesRepsResponse):
209
+ return result
210
+ return ListSalesRepsResponse(sales_reps=[], total=0)
211
+
212
+ def get_sales_rep(self, sales_rep_id: str, *, project_id: str) -> SalesRepResponse | None:
213
+ """Get a sales rep by ID."""
214
+ result = _get_sales_rep.sync(sales_rep_id, client=self._client, project_id=project_id)
215
+ return result if isinstance(result, SalesRepResponse) else None
216
+
217
+ def update_sales_rep(
218
+ self,
219
+ sales_rep_id: str,
220
+ *,
221
+ project_id: str,
222
+ code: str | None | Unset = UNSET,
223
+ name: str | None | Unset = UNSET,
224
+ email: str | None | Unset = UNSET,
225
+ user_id: str | None | Unset = UNSET,
226
+ default_commission_rate: float | str | None | Unset = UNSET,
227
+ is_active: bool | None | Unset = UNSET,
228
+ ext_data: dict[str, Any] | None | Unset = UNSET,
229
+ ) -> SalesRepResponse:
230
+ """Update a sales rep; pass ``None`` to clear nullable fields."""
231
+ body = UpdateSalesRepRequest(
232
+ code=code,
233
+ name=name,
234
+ email=email,
235
+ user_id=user_id,
236
+ default_commission_rate=default_commission_rate,
237
+ is_active=is_active,
238
+ ext_data=cast(Any, ext_data),
239
+ )
240
+ result = _update_sales_rep.sync(sales_rep_id, client=self._client, body=body, project_id=project_id)
241
+ return _expect_response(result, SalesRepResponse, "updating sales rep")
242
+
243
+ def delete_sales_rep(self, sales_rep_id: str, *, project_id: str) -> SalesRepResponse:
244
+ """Delete an unused sales rep, or deactivate one with customer/order history."""
245
+ result = _delete_sales_rep.sync(sales_rep_id, client=self._client, project_id=project_id)
246
+ return _expect_response(result, SalesRepResponse, "deleting sales rep")
@@ -303,6 +303,8 @@ class Sales:
303
303
  so_number: str,
304
304
  lines: list[CreateSalesOrderLineRequest | dict[str, Any]] | None = None,
305
305
  customer_id: str | None = None,
306
+ sales_rep_id: str | None = None,
307
+ commission_rate_snapshot: float | str | None | Unset = UNSET,
306
308
  channel_id: str | None = None,
307
309
  external_id: str | None = None,
308
310
  requested_ship_date: datetime | None = None,
@@ -315,6 +317,8 @@ class Sales:
315
317
  body = CreateSalesOrderRequest(
316
318
  so_number=so_number,
317
319
  customer_id=_optional(customer_id),
320
+ sales_rep_id=_optional(sales_rep_id),
321
+ commission_rate_snapshot=commission_rate_snapshot,
318
322
  channel_id=_optional(channel_id),
319
323
  external_id=_optional(external_id),
320
324
  requested_ship_date=_optional(requested_ship_date),
@@ -344,6 +348,7 @@ class Sales:
344
348
  project_id: str,
345
349
  lifecycle_status: CanonicalStatus | str | None = None,
346
350
  customer_id: str | None = None,
351
+ sales_rep_id: str | None = None,
347
352
  channel_id: str | None = None,
348
353
  limit: int = 50,
349
354
  offset: int = 0,
@@ -353,6 +358,7 @@ class Sales:
353
358
  client=self._client,
354
359
  lifecycle_status=cast(Any, _optional(_order_status(lifecycle_status))),
355
360
  customer_id=_optional(customer_id),
361
+ sales_rep_id=_optional(sales_rep_id),
356
362
  channel_id=_optional(channel_id),
357
363
  limit=limit,
358
364
  offset=offset,
@@ -9,17 +9,38 @@ from __future__ import annotations
9
9
  from typing import Any, TypeVar, cast
10
10
 
11
11
  from convexity_api_client import AuthenticatedClient, Client
12
+ from convexity_api_client.api.v1 import (
13
+ inventory_assign_item_warehouse_location as _assign_item_warehouse_location,
14
+ )
12
15
  from convexity_api_client.api.v1 import inventory_create_warehouse as _create_warehouse
13
16
  from convexity_api_client.api.v1 import (
14
17
  inventory_create_warehouse_location as _create_warehouse_location,
15
18
  )
16
19
  from convexity_api_client.api.v1 import inventory_get_warehouse as _get_warehouse
17
20
  from convexity_api_client.api.v1 import inventory_get_warehouse_location as _get_warehouse_location
21
+ from convexity_api_client.api.v1 import (
22
+ inventory_list_item_warehouse_locations as _list_item_warehouse_locations,
23
+ )
24
+ from convexity_api_client.api.v1 import (
25
+ inventory_list_warehouse_location_items as _list_warehouse_location_items,
26
+ )
18
27
  from convexity_api_client.api.v1 import inventory_list_warehouse_locations as _list_warehouse_locations
19
28
  from convexity_api_client.api.v1 import inventory_list_warehouses as _list_warehouses
20
29
  from convexity_api_client.api.v1 import inventory_update_warehouse as _update_warehouse
30
+ from convexity_api_client.models.assign_inventory_item_location_request import (
31
+ AssignInventoryItemLocationRequest,
32
+ )
21
33
  from convexity_api_client.models.create_warehouse_location_request import CreateWarehouseLocationRequest
22
34
  from convexity_api_client.models.create_warehouse_request import CreateWarehouseRequest
35
+ from convexity_api_client.models.inventory_item_location_assignment_response import (
36
+ InventoryItemLocationAssignmentResponse,
37
+ )
38
+ from convexity_api_client.models.list_item_warehouse_locations_response import (
39
+ ListItemWarehouseLocationsResponse,
40
+ )
41
+ from convexity_api_client.models.list_warehouse_location_items_response import (
42
+ ListWarehouseLocationItemsResponse,
43
+ )
23
44
  from convexity_api_client.models.list_warehouse_locations_response import ListWarehouseLocationsResponse
24
45
  from convexity_api_client.models.list_warehouses_response import ListWarehousesResponse
25
46
  from convexity_api_client.models.location_type import LocationType
@@ -121,6 +142,47 @@ class Warehouses:
121
142
  result = _update_warehouse.sync(warehouse_id, client=self._client, body=body, project_id=project_id)
122
143
  return _expect_response(result, WarehouseResponse, "updating warehouse")
123
144
 
145
+ def list_item_locations(
146
+ self,
147
+ item_id: str,
148
+ *,
149
+ project_id: str,
150
+ limit: int = 100,
151
+ offset: int = 0,
152
+ ) -> ListItemWarehouseLocationsResponse:
153
+ """List locations where an item is assigned or currently stocked."""
154
+ result = _list_item_warehouse_locations.sync(
155
+ item_id,
156
+ client=self._client,
157
+ project_id=project_id,
158
+ limit=limit,
159
+ offset=offset,
160
+ )
161
+ if isinstance(result, ListItemWarehouseLocationsResponse):
162
+ return result
163
+ return ListItemWarehouseLocationsResponse(items=[], total=0)
164
+
165
+ def assign_item_location(
166
+ self,
167
+ item_id: str,
168
+ warehouse_location_id: str,
169
+ *,
170
+ project_id: str,
171
+ ext_data: dict[str, Any] | None = None,
172
+ ) -> InventoryItemLocationAssignmentResponse:
173
+ """Assign an item to a location, reactivating an existing assignment."""
174
+ body = AssignInventoryItemLocationRequest(
175
+ warehouse_location_id=warehouse_location_id,
176
+ ext_data=cast(Any, _optional(ext_data)),
177
+ )
178
+ result = _assign_item_warehouse_location.sync(
179
+ item_id,
180
+ client=self._client,
181
+ body=body,
182
+ project_id=project_id,
183
+ )
184
+ return _expect_response(result, InventoryItemLocationAssignmentResponse, "assigning item to location")
185
+
124
186
  # -- WarehouseLocation ----------------------------------------------------
125
187
 
126
188
  def create_location(
@@ -197,3 +259,25 @@ class Warehouses:
197
259
  if isinstance(result, ListWarehouseLocationsResponse):
198
260
  return result
199
261
  return ListWarehouseLocationsResponse(items=[], total=0)
262
+
263
+ def list_location_items(
264
+ self,
265
+ warehouse_id: str,
266
+ location_id: str,
267
+ *,
268
+ project_id: str,
269
+ limit: int = 100,
270
+ offset: int = 0,
271
+ ) -> ListWarehouseLocationItemsResponse:
272
+ """List items assigned to or currently stocked at a location."""
273
+ result = _list_warehouse_location_items.sync(
274
+ warehouse_id,
275
+ location_id,
276
+ client=self._client,
277
+ project_id=project_id,
278
+ limit=limit,
279
+ offset=offset,
280
+ )
281
+ if isinstance(result, ListWarehouseLocationItemsResponse):
282
+ return result
283
+ return ListWarehouseLocationItemsResponse(items=[], total=0)
@@ -0,0 +1,55 @@
1
+ """Create a sales rep, assign a customer, and snapshot commission on an order."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import uuid
6
+
7
+ from convexity_sdk import ConvexityClient
8
+
9
+ ORG_SLUG = "convexity-sdk-samples"
10
+ PROJECT_SLUG = "griffin-it"
11
+
12
+
13
+ def find_project_id(client: ConvexityClient) -> str:
14
+ organization = client.organizations.get_by_slug(ORG_SLUG)
15
+ if organization is None:
16
+ raise RuntimeError(f"Organization '{ORG_SLUG}' not found. Run ../create_org_and_project.py first.")
17
+ project = client.projects.get_by_slug(organization.id, PROJECT_SLUG)
18
+ if project is None:
19
+ raise RuntimeError(f"Project '{PROJECT_SLUG}' not found. Run ../create_org_and_project.py first.")
20
+ return project.id
21
+
22
+
23
+ def main() -> None:
24
+ client = ConvexityClient()
25
+ project_id = find_project_id(client)
26
+ suffix = uuid.uuid4().hex[:8].upper()
27
+
28
+ sales_rep = client.crm.create_sales_rep(
29
+ project_id=project_id,
30
+ code=f"SDK-REP-{suffix}",
31
+ name="SDK Sample Rep",
32
+ email=f"rep-{suffix.lower()}@example.com",
33
+ default_commission_rate="0.075",
34
+ )
35
+ customer = client.crm.create_customer(
36
+ project_id=project_id,
37
+ code=f"SDK-CUST-{suffix}",
38
+ name="SDK Sales Rep Customer",
39
+ sales_rep_id=sales_rep.id,
40
+ )
41
+ order = client.sales.create_order(
42
+ project_id=project_id,
43
+ so_number=f"SDK-SO-{suffix}",
44
+ customer_id=customer.id,
45
+ lines=[],
46
+ )
47
+
48
+ print(f"Sales rep: {sales_rep.code} ({sales_rep.id})")
49
+ print(f"Customer default rep: {customer.sales_rep_id}")
50
+ print(f"Order rep: {order.sales_rep_id}")
51
+ print(f"Commission snapshot: {order.commission_rate_snapshot}")
52
+
53
+
54
+ if __name__ == "__main__":
55
+ main()
@@ -0,0 +1,38 @@
1
+ """List the assigned and stocked items visible in a warehouse location.
2
+
3
+ Set ``CONVEXITY_PROJECT_ID``, ``CONVEXITY_WAREHOUSE_ID``, and
4
+ ``CONVEXITY_LOCATION_ID`` before running this sample.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import os
10
+
11
+ from convexity_sdk import ConvexityClient
12
+
13
+
14
+ def require_env(name: str) -> str:
15
+ value = os.getenv(name)
16
+ if value:
17
+ return value
18
+ raise RuntimeError(f"Set {name} before running this sample")
19
+
20
+
21
+ def main() -> None:
22
+ client = ConvexityClient()
23
+ contents = client.warehouses.list_location_items(
24
+ require_env("CONVEXITY_WAREHOUSE_ID"),
25
+ require_env("CONVEXITY_LOCATION_ID"),
26
+ project_id=require_env("CONVEXITY_PROJECT_ID"),
27
+ )
28
+ print(f"{contents.total} item(s) assigned to or stocked at this location")
29
+ for item in contents.items:
30
+ assignment_state = "assigned" if item.is_assigned else "stocked"
31
+ print(
32
+ f"{item.sku}: {item.name} — {assignment_state}, "
33
+ f"on hand {item.on_hand_qty}, available {item.available_qty}"
34
+ )
35
+
36
+
37
+ if __name__ == "__main__":
38
+ main()
@@ -0,0 +1,38 @@
1
+ """List warehouses and locations where an item is assigned or stocked.
2
+
3
+ Set ``CONVEXITY_PROJECT_ID`` and ``CONVEXITY_INVENTORY_ITEM_ID`` before
4
+ running this sample.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import os
10
+
11
+ from convexity_sdk import ConvexityClient
12
+
13
+
14
+ def require_env(name: str) -> str:
15
+ value = os.getenv(name)
16
+ if value:
17
+ return value
18
+ raise RuntimeError(f"Set {name} before running this sample")
19
+
20
+
21
+ def main() -> None:
22
+ client = ConvexityClient()
23
+ locations = client.warehouses.list_item_locations(
24
+ require_env("CONVEXITY_INVENTORY_ITEM_ID"),
25
+ project_id=require_env("CONVEXITY_PROJECT_ID"),
26
+ )
27
+ print(f"{locations.total} warehouse location(s)")
28
+ for location in locations.items:
29
+ state = "assigned" if location.is_assigned else "stocked"
30
+ print(
31
+ f"{location.warehouse_code} / {location.location_name}: "
32
+ f"{state}, on hand {location.on_hand_qty}, "
33
+ f"available {location.available_qty}"
34
+ )
35
+
36
+
37
+ if __name__ == "__main__":
38
+ main()
@@ -0,0 +1,20 @@
1
+ """Assign an inventory item to a warehouse location.
2
+
3
+ Set CONVEXITY_PROJECT_ID, CONVEXITY_ITEM_ID, and
4
+ CONVEXITY_WAREHOUSE_LOCATION_ID before running this sample.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import os
10
+
11
+ from convexity_sdk import ConvexityClient
12
+
13
+ client = ConvexityClient()
14
+ assignment = client.warehouses.assign_item_location(
15
+ os.environ["CONVEXITY_ITEM_ID"],
16
+ os.environ["CONVEXITY_WAREHOUSE_LOCATION_ID"],
17
+ project_id=os.environ["CONVEXITY_PROJECT_ID"],
18
+ )
19
+
20
+ print(f"Assigned {assignment.inventory_item_id} to {assignment.warehouse_location_id}")