ms-salesforce-api 2.24.0.dev5__tar.gz → 2.24.0.dev6__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 (86) hide show
  1. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/PKG-INFO +1 -1
  2. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/account/dto/AccountDTO.py +3 -2
  3. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/opportunity/__init__.py +1 -2
  4. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/opportunity/dto/OpportunityDTO.py +3 -3
  5. ms_salesforce_api-2.24.0.dev6/ms_salesforce_api/salesforce/api/project/__init__.py +101 -0
  6. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/project/dto/OpportunityDTO.py +3 -1
  7. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/project/dto/ProjectLineItemDTO.py +15 -1
  8. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/pyproject.toml +1 -1
  9. ms_salesforce_api-2.24.0.dev5/ms_salesforce_api/salesforce/api/project/__init__.py +0 -109
  10. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/LICENSE +0 -0
  11. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/README.md +0 -0
  12. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/__init__.py +0 -0
  13. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/Auth.py +0 -0
  14. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/JWTGenerator.py +0 -0
  15. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/SalesforceQueryExecutor.py +0 -0
  16. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/__init__.py +0 -0
  17. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/__tests__/__init__.py +0 -0
  18. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/__tests__/test_Auth.py +0 -0
  19. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/__tests__/test_JWTGenerator.py +0 -0
  20. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/__tests__/test_SalesforceRequester.py +0 -0
  21. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/__init__.py +0 -0
  22. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/account/__init__.py +0 -0
  23. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/account/constants.py +0 -0
  24. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/account/dto/__init__.py +0 -0
  25. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/account/export_data/Bigquery.py +0 -0
  26. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/account/export_data/__init__.py +0 -0
  27. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/contact/__init__.py +0 -0
  28. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/contact/constants.py +0 -0
  29. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/contact/dto/ContactDTO.py +0 -0
  30. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/contact/dto/__init__.py +0 -0
  31. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/contact/export_data/Bigquery.py +0 -0
  32. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/contact/export_data/__init__.py +0 -0
  33. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/lead/__init__.py +0 -0
  34. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/lead/constants.py +0 -0
  35. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/lead/dto/LeadDTO.py +0 -0
  36. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/lead/dto/__init__.py +0 -0
  37. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/lead/export_data/Bigquery.py +0 -0
  38. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/lead/export_data/__init__.py +0 -0
  39. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/opportunity/constants.py +0 -0
  40. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/opportunity/dto/__init__.py +0 -0
  41. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/opportunity/export_data/Bigquery.py +0 -0
  42. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/opportunity/export_data/CloudSQL.py +0 -0
  43. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/opportunity/export_data/__init__.py +0 -0
  44. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/opportunity/export_data/__tests__/__init__.py +0 -0
  45. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/opportunity/export_data/__tests__/test_CloudSQL.py +0 -0
  46. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/opportunity/helpers.py +0 -0
  47. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/opportunity_contact_role/__init__.py +0 -0
  48. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/opportunity_contact_role/constants.py +0 -0
  49. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/opportunity_contact_role/dto/OpportunityContactDTO.py +0 -0
  50. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/opportunity_contact_role/dto/__init__.py +0 -0
  51. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/opportunity_contact_role/export_data/Bigquery.py +0 -0
  52. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/opportunity_contact_role/export_data/__init__.py +0 -0
  53. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/opportunity_history/__init__.py +0 -0
  54. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/opportunity_history/constants.py +0 -0
  55. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/opportunity_history/dto/OpportunityDTO.py +0 -0
  56. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/opportunity_history/dto/__init__.py +0 -0
  57. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/opportunity_history/export_data/Bigquery.py +0 -0
  58. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/opportunity_history/export_data/__init__.py +0 -0
  59. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/product/__init__.py +0 -0
  60. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/product/__tests__/__init__.py +0 -0
  61. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/product/__tests__/test_Product.py +0 -0
  62. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/product/constants.py +0 -0
  63. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/product/dto/ProductDTO.py +0 -0
  64. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/product/dto/__init__.py +0 -0
  65. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/product/export_data/Bigquery.py +0 -0
  66. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/product/export_data/__init__.py +0 -0
  67. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/profit_center/__init__.py +0 -0
  68. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/profit_center/__tests__/__init__.py +0 -0
  69. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/profit_center/__tests__/test_ProfitCenter.py +0 -0
  70. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/profit_center/constants.py +0 -0
  71. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/profit_center/dto/ProfitCenterDTO.py +0 -0
  72. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/profit_center/dto/__init__.py +0 -0
  73. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/profit_center/export_data/Bigquery.py +0 -0
  74. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/profit_center/export_data/__init__.py +0 -0
  75. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/project/__tests__/__init__.py +0 -0
  76. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/project/__tests__/test_Project.py +0 -0
  77. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/project/constants.py +0 -0
  78. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/project/dto/BillingLineDTO.py +0 -0
  79. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/project/dto/__init__.py +0 -0
  80. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/project/export_data/Bigquery.py +0 -0
  81. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/project/export_data/CloudSQL.py +0 -0
  82. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/project/export_data/__init__.py +0 -0
  83. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/project/export_data/__tests__/__init__.py +0 -0
  84. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/api/project/export_data/__tests__/test_CloudSQL.py +0 -0
  85. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/helpers/__init__.py +0 -0
  86. {ms_salesforce_api-2.24.0.dev5 → ms_salesforce_api-2.24.0.dev6}/ms_salesforce_api/salesforce/helpers/string.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ms-salesforce-api
3
- Version: 2.24.0.dev5
3
+ Version: 2.24.0.dev6
4
4
  Summary: Python library used to extract data from Salesforce API and migrate it to Bigquery and Postgres.
5
5
  Author: Making Science
6
6
  Requires-Python: >=3.8.1,<4.0.0
@@ -327,9 +327,10 @@ class AccountDTO(object):
327
327
  owner_email=normalize_value(_get_owner_email()),
328
328
  type=normalize_value(record["Type"]),
329
329
  industry=normalize_value(record["Industry"]),
330
-
331
330
  risk_assessment=normalize_value(record["Risk_Assessment__c"]),
332
- risk_assessment_date=normalize_value(record["Risk_Assessment_Date__c"]),
331
+ risk_assessment_date=normalize_value(
332
+ record["Risk_Assessment_Date__c"]
333
+ ),
333
334
  )
334
335
 
335
336
  def to_dict(self):
@@ -37,8 +37,7 @@ class Opportunity(SalesforceQueryExecutor):
37
37
  return []
38
38
 
39
39
  opportunities = [
40
- OpportunityDTO.from_salesforce_record(record)
41
- for record in data
40
+ OpportunityDTO.from_salesforce_record(record) for record in data
42
41
  ]
43
42
  opportunities_list = list(opportunities)
44
43
 
@@ -478,7 +478,9 @@ class OpportunityDTO(object):
478
478
  record.get("Servicios_Asociados__c", "")
479
479
  ),
480
480
  stage_name=normalize_value(record.get("StageName", "")),
481
- start_date=normalize_value(record.get("DT_ProjectStartDate__c", "")),
481
+ start_date=normalize_value(
482
+ record.get("DT_ProjectStartDate__c", "")
483
+ ),
482
484
  tier_short=normalize_value(record.get("Tier_Short__c", "")),
483
485
  total_opportunity_quantity=normalize_value(
484
486
  record.get("TotalOpportunityQuantity", "")
@@ -509,7 +511,6 @@ class OpportunityDTO(object):
509
511
  finance_contact=record["MAIL_FinanceContact__c"],
510
512
  convertAmount=record["convertAmount"],
511
513
  project_code=record["FRM_ProjectCode__c"],
512
-
513
514
  google_drive_link=record["FRM_GoogleDriveLink__c"],
514
515
  project_status=record["PCK_ProjectStatus__c"],
515
516
  pck_division=record["PCK_Division__c"],
@@ -601,5 +602,4 @@ class OpportunityDTO(object):
601
602
  "out_of_report": self.out_of_report,
602
603
  "billing_info": self.billing_info,
603
604
  "parent_opportunity": self.parent_opportunity,
604
-
605
605
  }
@@ -0,0 +1,101 @@
1
+ import logging
2
+ from concurrent.futures import ThreadPoolExecutor
3
+
4
+ from ms_salesforce_api.salesforce.api.project.constants import (
5
+ DEFAULT_PROJECT_BILLING_LINE_QUERY,
6
+ DEFAULT_PROJECT_OPPORTUNITY_QUERY,
7
+ )
8
+ from ms_salesforce_api.salesforce.api.project.dto.BillingLineDTO import (
9
+ BillingLineDTO,
10
+ )
11
+ from ms_salesforce_api.salesforce.api.project.dto.OpportunityDTO import (
12
+ OpportunityDTO,
13
+ )
14
+ from ms_salesforce_api.salesforce.SalesforceQueryExecutor import (
15
+ SalesforceQueryExecutor,
16
+ )
17
+
18
+ logging.basicConfig(
19
+ level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s"
20
+ )
21
+
22
+ MAX_PROJECT_IDS_PER_QUERY = 200
23
+
24
+
25
+ class Project(SalesforceQueryExecutor):
26
+ def fetch_billing_lines(self, project_ids):
27
+ billing_lines = []
28
+ query = DEFAULT_PROJECT_BILLING_LINE_QUERY.format(
29
+ project_id="','".join(project_ids)
30
+ )
31
+
32
+ data = self.fetch_data(query)
33
+ if data is not None:
34
+ billing_lines.extend(data)
35
+
36
+ return billing_lines
37
+
38
+ def get_batches(self, lst, n):
39
+ """Yield successive n-sized chunks from lst."""
40
+ for i in range(0, len(lst), n):
41
+ yield lst[i : i + n] # noqa: E203
42
+
43
+ def get_all(
44
+ self,
45
+ last_executed_at: str = None,
46
+ query: str = DEFAULT_PROJECT_OPPORTUNITY_QUERY,
47
+ format: str = "json",
48
+ ):
49
+ if last_executed_at:
50
+ query = query + f"WHERE CreatedDate > {last_executed_at}"
51
+
52
+ data = self.fetch_data(query)
53
+ if data is None:
54
+ logging.error(
55
+ "[ERROR - SalesforceAPI]: No projects data return from Salesforce API" # noqa: E501
56
+ )
57
+ return []
58
+
59
+ opportunities = {
60
+ record["Id"]: OpportunityDTO.from_salesforce_record(record)
61
+ for record in data
62
+ }
63
+
64
+ project_ids = list(opportunities.keys())
65
+
66
+ with ThreadPoolExecutor(max_workers=10) as executor:
67
+ for project_id_batch in self.get_batches(
68
+ project_ids,
69
+ MAX_PROJECT_IDS_PER_QUERY,
70
+ ):
71
+ batch_results = list(
72
+ executor.map(
73
+ self.fetch_billing_lines,
74
+ [project_id_batch],
75
+ )
76
+ )
77
+ for billing_line_data in batch_results:
78
+ for record in billing_line_data:
79
+ project_id = record["Project_Line_Item__r"][
80
+ "Project__c"
81
+ ]
82
+ opportunity = opportunities.get(project_id)
83
+
84
+ billing_line_dto = (
85
+ BillingLineDTO.from_salesforce_record(
86
+ record,
87
+ opportunity.projectcode,
88
+ )
89
+ )
90
+
91
+ if opportunity is not None:
92
+ if not opportunity.billing_lines:
93
+ opportunity.billing_lines = []
94
+ opportunity.billing_lines.append(billing_line_dto)
95
+ opportunities_list = list(opportunities.values())
96
+ if format == "json":
97
+ opportunities_list = [
98
+ opportunity.to_dict() for opportunity in opportunities_list
99
+ ]
100
+
101
+ return opportunities_list
@@ -546,7 +546,9 @@ class OpportunityDTO(object):
546
546
 
547
547
  def _get_opportunity_project_code():
548
548
  try:
549
- return normalize_value(record["Opportunity__r"]["FRM_ProjectCode__c"])
549
+ return normalize_value(
550
+ record["Opportunity__r"]["FRM_ProjectCode__c"]
551
+ )
550
552
  except (TypeError, KeyError):
551
553
  return ""
552
554
 
@@ -47,11 +47,25 @@ class ProjectLineItemDTO:
47
47
  except Exception:
48
48
  return ""
49
49
 
50
+ def _get_opportunity_project_code():
51
+ try:
52
+ project = record.get("Project__r")
53
+ opportunity = project.get("Opportunity__r") if project else {}
54
+ opportunity_project_code = opportunity.get(
55
+ "FRM_ProjectCode__c"
56
+ )
57
+
58
+ return opportunity_project_code
59
+
60
+ except AttributeError:
61
+ return None
62
+
50
63
  product_name = (
51
64
  record.get("ProductNew__r", {}).get("Name")
52
65
  if record.get("ProductNew__r")
53
66
  else None
54
67
  )
68
+
55
69
  return cls(
56
70
  id=record.get("Id"),
57
71
  created_date=_parse_created_date(record.get("CreatedDate")),
@@ -68,7 +82,7 @@ class ProjectLineItemDTO:
68
82
  ms_pli_name=record.get("MS_PLI_Name__c"),
69
83
  country=record.get("Country__c"),
70
84
  project_id=project_id,
71
- opportunity_project_code=record.get("Project__r", {}).get("Opportunity__r", {}).get("FRM_ProjectCode__c"),
85
+ opportunity_project_code=_get_opportunity_project_code(),
72
86
  )
73
87
 
74
88
  def to_dict(self):
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "ms-salesforce-api"
3
- version = "2.24.0.dev5"
3
+ version = "2.24.0.dev6"
4
4
  description = "Python library used to extract data from Salesforce API and migrate it to Bigquery and Postgres."
5
5
  authors = ["Making Science"]
6
6
  readme = "README.md"
@@ -1,109 +0,0 @@
1
- import logging
2
- from concurrent.futures import ThreadPoolExecutor
3
-
4
- from ms_salesforce_api.salesforce.api.project.constants import (
5
- DEFAULT_PROJECT_BILLING_LINE_QUERY,
6
- DEFAULT_PROJECT_OPPORTUNITY_QUERY,
7
- )
8
- from ms_salesforce_api.salesforce.api.project.dto.BillingLineDTO import (
9
- BillingLineDTO,
10
- )
11
- from ms_salesforce_api.salesforce.api.project.dto.OpportunityDTO import (
12
- OpportunityDTO,
13
- )
14
- from ms_salesforce_api.salesforce.SalesforceQueryExecutor import (
15
- SalesforceQueryExecutor,
16
- )
17
-
18
- logging.basicConfig(
19
- level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s"
20
- )
21
-
22
- MAX_PROJECT_IDS_PER_QUERY = 200
23
-
24
-
25
- class Project(SalesforceQueryExecutor):
26
- def fetch_billing_lines(self, project_ids):
27
- billing_lines = []
28
- query = DEFAULT_PROJECT_BILLING_LINE_QUERY.format(
29
- project_id="','".join(project_ids)
30
- )
31
-
32
- data = self.fetch_data(query)
33
- if data is not None:
34
- billing_lines.extend(data)
35
-
36
- return billing_lines
37
-
38
- def get_batches(self, lst, n):
39
- """Yield successive n-sized chunks from lst."""
40
- for i in range(0, len(lst), n):
41
- yield lst[i : i + n] # noqa: E203
42
-
43
- def get_all(
44
- self,
45
- last_executed_at: str = None,
46
- query: str = DEFAULT_PROJECT_OPPORTUNITY_QUERY,
47
- format: str = "json",
48
- ):
49
- try:
50
- if last_executed_at:
51
- query = query + f"WHERE CreatedDate > {last_executed_at}"
52
-
53
- data = self.fetch_data(query)
54
- if data is None:
55
- logging.error(
56
- "[ERROR - SalesforceAPI]: No projects data return from Salesforce API" # noqa: E501
57
- )
58
- return []
59
-
60
- opportunities = {
61
- record["Id"]: OpportunityDTO.from_salesforce_record(record)
62
- for record in data
63
- }
64
-
65
- project_ids = list(opportunities.keys())
66
-
67
- with ThreadPoolExecutor(max_workers=10) as executor:
68
- for project_id_batch in self.get_batches(
69
- project_ids,
70
- MAX_PROJECT_IDS_PER_QUERY,
71
- ):
72
- batch_results = list(
73
- executor.map(
74
- self.fetch_billing_lines,
75
- [project_id_batch],
76
- )
77
- )
78
- for billing_line_data in batch_results:
79
- for record in billing_line_data:
80
- project_id = record["Project_Line_Item__r"][
81
- "Project__c"
82
- ]
83
- opportunity = opportunities.get(project_id)
84
-
85
- billing_line_dto = (
86
- BillingLineDTO.from_salesforce_record(
87
- record,
88
- opportunity.projectcode,
89
- )
90
- )
91
-
92
- if opportunity is not None:
93
- if not opportunity.billing_lines:
94
- opportunity.billing_lines = []
95
- opportunity.billing_lines.append(
96
- billing_line_dto
97
- )
98
- opportunities_list = list(opportunities.values())
99
- if format == "json":
100
- opportunities_list = [
101
- opportunity.to_dict() for opportunity in opportunities_list
102
- ]
103
-
104
- return opportunities_list
105
- except Exception as e:
106
- logging.error(
107
- f"[ERROR - get_all]: Failed to get opportunities: {e}"
108
- )
109
- return []