cc-py-commons 0.5.15__tar.gz → 0.5.35__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 (154) hide show
  1. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/PKG-INFO +1 -1
  2. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/bids/bid_schema.py +13 -13
  3. cc_py_commons-0.5.35/cc_py_commons/carriers/account_carrier_map.py +12 -0
  4. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/carriers/account_carrier_map_schema.py +6 -7
  5. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/carriers/carrier_schema.py +2 -2
  6. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/config/env.py +5 -0
  7. cc_py_commons-0.5.35/cc_py_commons/config/web_socket_action.py +3 -0
  8. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/geolocate.py +36 -23
  9. cc_py_commons-0.5.35/cc_py_commons/loads/equipment_schema.py +16 -0
  10. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/loads/load.py +1 -0
  11. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/loads/load_schema.py +1 -0
  12. cc_py_commons-0.5.35/cc_py_commons/services/booking_agent/get_quote_by_load_id.py +19 -0
  13. cc_py_commons-0.5.35/cc_py_commons/services/booking_agent/list_bids.py +33 -0
  14. cc_py_commons-0.5.35/cc_py_commons/services/booking_agent/list_quotes.py +27 -0
  15. cc_py_commons-0.5.35/cc_py_commons/services/c4/get_account_settings.py +27 -0
  16. cc_py_commons-0.5.35/cc_py_commons/services/web_socket/send_notification.py +38 -0
  17. cc_py_commons-0.5.35/cc_py_commons/sqs/booking_assistant_cancel_quote_notification.py +31 -0
  18. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/sqs/booking_assistant_flow_event.py +3 -2
  19. cc_py_commons-0.5.35/cc_py_commons/sqs/sqs_service.py +86 -0
  20. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/tests/test_map_transaction.py +1 -0
  21. cc_py_commons-0.5.35/cc_py_commons/tests/test_web_socket_send_notification.py +39 -0
  22. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/transactions/map_transaction.py +1 -0
  23. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/transactions/transaction.py +1 -0
  24. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/transactions/transaction_schema.py +1 -0
  25. cc_py_commons-0.5.35/cc_py_commons/utils/__init__.py +0 -0
  26. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/utils/bulk_lane_price_result_utils.py +3 -0
  27. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons.egg-info/PKG-INFO +1 -1
  28. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons.egg-info/SOURCES.txt +8 -1
  29. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/setup.py +1 -1
  30. cc_py_commons-0.5.15/cc_py_commons/carriers/account_carrier_map.py +0 -12
  31. cc_py_commons-0.5.15/cc_py_commons/loads/equipment_schema.py +0 -14
  32. cc_py_commons-0.5.15/cc_py_commons/services/c4/get_account_settings.py +0 -21
  33. cc_py_commons-0.5.15/cc_py_commons/services/mercury/get_lane_price_for_bulk.py +0 -23
  34. cc_py_commons-0.5.15/cc_py_commons/sqs/sqs_service.py +0 -25
  35. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/README.md +0 -0
  36. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/__init__.py +0 -0
  37. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/bids/__init__.py +0 -0
  38. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/bids/bid.py +0 -0
  39. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/bids/bid_history.py +0 -0
  40. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/bids/bid_history_schema.py +0 -0
  41. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/carriers/__init__.py +0 -0
  42. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/carriers/carrier.py +0 -0
  43. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/carriers/contact.py +0 -0
  44. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/carriers/contact_schema.py +0 -0
  45. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/config/__init__.py +0 -0
  46. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/config/c4_account_settings.py +0 -0
  47. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/config/mcleod_load_fields.py +0 -0
  48. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/config/pc_miler_config.py +0 -0
  49. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/db/__init__.py +0 -0
  50. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/db/connection.py +0 -0
  51. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/lanes/__init__.py +0 -0
  52. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/lanes/carrier_lane.py +0 -0
  53. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/lanes/carrier_lane_schema.py +0 -0
  54. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/lanes/lane.py +0 -0
  55. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/lanes/lane_schema.py +0 -0
  56. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/loads/__init__.py +0 -0
  57. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/loads/equipment.py +0 -0
  58. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/loads/equipment_types.py +0 -0
  59. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/loads/freighthub_contact.py +0 -0
  60. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/loads/freighthub_contact_schema.py +0 -0
  61. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/loads/load_status.py +0 -0
  62. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/loads/location.py +0 -0
  63. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/loads/location_schema.py +0 -0
  64. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/loads/map_load_response.py +0 -0
  65. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/quotes/__init__.py +0 -0
  66. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/quotes/quote.py +0 -0
  67. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/quotes/quote_schema.py +0 -0
  68. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/quotes/quote_status.py +0 -0
  69. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/rfp/__init__.py +0 -0
  70. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/rfp/create_table.py +0 -0
  71. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/rfp/rfp_status.py +0 -0
  72. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/rfp/truck_lane_search_mapper.py +0 -0
  73. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/schemas/__init__.py +0 -0
  74. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/schemas/camel_case_schema.py +0 -0
  75. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/services/__init__.py +0 -0
  76. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/services/analytics/__init__.py +0 -0
  77. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/services/analytics/analytics_event.py +0 -0
  78. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/services/booking_agent/__init__.py +0 -0
  79. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/services/booking_agent/accept_bid.py +0 -0
  80. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/services/booking_agent/cancel_bid.py +0 -0
  81. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/services/booking_agent/constants.py +0 -0
  82. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/services/booking_agent/counter_bid.py +0 -0
  83. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/services/booking_agent/decline_bid.py +0 -0
  84. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/services/booking_agent/get_bid_by_amazon_order_id.py +0 -0
  85. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/services/booking_agent/get_quote.py +0 -0
  86. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/services/booking_agent/update_bid.py +0 -0
  87. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/services/c4/__init__.py +0 -0
  88. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/services/c4/amazon_session_token.py +0 -0
  89. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/services/c4/constants.py +0 -0
  90. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/services/c4/get_account.py +0 -0
  91. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/services/c4/get_integration.py +0 -0
  92. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/services/c4/get_users_for_account.py +0 -0
  93. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/services/c4/refresh_amazon_token.py +0 -0
  94. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/services/carrier_hub/__init__.py +0 -0
  95. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/services/carrier_hub/get_carrier.py +0 -0
  96. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/services/carrier_hub/list_carriers.py +0 -0
  97. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/services/carrier_hub/list_contacts.py +0 -0
  98. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/services/carrier_hub/update_contact.py +0 -0
  99. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/services/freight_hub/__init__.py +0 -0
  100. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/services/freight_hub/post_freight_hub_load.py +0 -0
  101. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/services/mercury/__init__.py +0 -0
  102. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/services/mercury/create_account_folder.py +0 -0
  103. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/services/mercury/db/__init__.py +0 -0
  104. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/services/mercury/db/delete_table.py +0 -0
  105. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/services/mercury/get_client.py +0 -0
  106. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/services/mercury/get_green_screens_lane_price.py +0 -0
  107. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/services/mercury/get_import_stat.py +0 -0
  108. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/services/mercury/get_lane_price.py +0 -0
  109. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/services/mercury/list_clients.py +0 -0
  110. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/services/mercury/post_import_stat.py +0 -0
  111. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/services/mercury/update_import_stat.py +0 -0
  112. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/services/slack/__init__.py +0 -0
  113. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/services/slack/send_slack_message.py +0 -0
  114. {cc_py_commons-0.5.15/cc_py_commons/sns → cc_py_commons-0.5.35/cc_py_commons/services/web_socket}/__init__.py +0 -0
  115. {cc_py_commons-0.5.15/cc_py_commons/sns/booking_agent → cc_py_commons-0.5.35/cc_py_commons/sns}/__init__.py +0 -0
  116. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/sns/book_load_notification.py +0 -0
  117. {cc_py_commons-0.5.15/cc_py_commons/sqs → cc_py_commons-0.5.35/cc_py_commons/sns/booking_agent}/__init__.py +0 -0
  118. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/sns/booking_agent/bid_counter_failure_notification.py +0 -0
  119. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/sns/booking_agent/constants.py +0 -0
  120. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/sns/booking_agent/send_sns_notification.py +0 -0
  121. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/sns/booking_assistant_flow_notification.py +0 -0
  122. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/sns/import_movements_notification.py +0 -0
  123. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/sns/parsed_carrier_notification.py +0 -0
  124. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/sns/sns_service.py +0 -0
  125. {cc_py_commons-0.5.15/cc_py_commons/tests → cc_py_commons-0.5.35/cc_py_commons/sqs}/__init__.py +0 -0
  126. {cc_py_commons-0.5.15/cc_py_commons/transactions → cc_py_commons-0.5.35/cc_py_commons/tests}/__init__.py +0 -0
  127. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/tests/test_case_conversion.py +0 -0
  128. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/tests/test_lambda_utils.py +0 -0
  129. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/tests/test_temperature_utils.py +0 -0
  130. {cc_py_commons-0.5.15/cc_py_commons/utils → cc_py_commons-0.5.35/cc_py_commons/transactions}/__init__.py +0 -0
  131. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/transactions/equipment_clas_schema.py +0 -0
  132. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/transactions/equipment_class.py +0 -0
  133. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/transactions/equipment_mapping.py +0 -0
  134. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/transactions/equipment_mapping_schema.py +0 -0
  135. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/utils/case_conversion.py +0 -0
  136. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/utils/datadog_logger.py +0 -0
  137. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/utils/datetimes.py +0 -0
  138. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/utils/dimension_utils.py +0 -0
  139. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/utils/geocode_location.py +0 -0
  140. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/utils/get_delivery_date.py +0 -0
  141. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/utils/json_logger.py +0 -0
  142. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/utils/lambda_utils.py +0 -0
  143. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/utils/local_file.py +0 -0
  144. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/utils/logger.py +0 -0
  145. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/utils/logger_v2.py +0 -0
  146. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/utils/pc_miler_utils.py +0 -0
  147. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/utils/price_utils.py +0 -0
  148. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/utils/redis.py +0 -0
  149. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/utils/s3_file.py +0 -0
  150. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons/utils/temperature_utils.py +0 -0
  151. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons.egg-info/dependency_links.txt +0 -0
  152. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons.egg-info/requires.txt +0 -0
  153. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/cc_py_commons.egg-info/top_level.txt +0 -0
  154. {cc_py_commons-0.5.15 → cc_py_commons-0.5.35}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cc_py_commons
3
- Version: 0.5.15
3
+ Version: 0.5.35
4
4
  Summary: Common code for microservices
5
5
  Home-page: https://github.com/Cargo-Chief/py-commons
6
6
  Author: CargoChief
@@ -10,26 +10,26 @@ class BidSchema(CamelCaseSchema):
10
10
  id = fields.UUID()
11
11
  quote_id = fields.UUID()
12
12
  carrier_id = fields.UUID()
13
- receipt_id = fields.String(allow_none=True)
13
+ receipt_id = fields.String(allow_none=True, missing=None)
14
14
  amount = fields.Integer()
15
- estimated_days = fields.Integer()
16
- notes = fields.String(allow_none=True)
15
+ estimated_days = fields.Integer(allow_none=True, missing=None)
16
+ notes = fields.String(allow_none=True, missing=None)
17
17
  match_score = fields.Float(allow_none=True)
18
18
  status_id = fields.UUID()
19
19
  pickup_date = fields.Date()
20
20
  delivery_date = fields.Date()
21
- decline_reason = fields.String(allow_none=True)
21
+ decline_reason = fields.String(allow_none=True, missing=None)
22
22
  bid_histories = fields.List(fields.Nested(BidHistorySchema), allow_none=True)
23
23
  origin_deadhead = fields.Float(allow_none=True)
24
- porus_truck_id = fields.UUID(allow_none=True)
25
- truck_lane_id = fields.UUID(allow_none=True)
26
- distance = fields.Float(allow_none=True)
27
- origin_city = fields.String()
28
- origin_state = fields.String()
29
- origin_zip = fields.String(allow_none=True)
30
- dest_city = fields.String()
31
- dest_state = fields.String()
32
- dest_zip = fields.String(allow_none=True)
24
+ porus_truck_id = fields.UUID(allow_none=True, missing=None)
25
+ truck_lane_id = fields.UUID(allow_none=True, missing=None)
26
+ distance = fields.Float(allow_none=True, missing=None)
27
+ origin_city = fields.String(missing=None)
28
+ origin_state = fields.String(missing=None)
29
+ origin_zip = fields.String(allow_none=True, missing=None)
30
+ dest_city = fields.String(missing=None)
31
+ dest_state = fields.String(missing=None)
32
+ dest_zip = fields.String(allow_none=True, missing=None)
33
33
  invite_emailed_at = fields.DateTime(allow_none=True)
34
34
 
35
35
  @post_load
@@ -0,0 +1,12 @@
1
+ import datetime
2
+ import uuid
3
+ from dataclasses import dataclass, field
4
+
5
+ @dataclass
6
+ class AccountCarrierMap:
7
+ account_id: int
8
+ carrier_id: uuid.UUID
9
+ status: str
10
+ customer_code: str = field(default=None)
11
+ warmup_email_sent_at: datetime.date = field(default=None)
12
+ no_dispatch: bool = field(default=False)
@@ -1,18 +1,17 @@
1
1
  from marshmallow import fields, EXCLUDE, post_load
2
2
  from cc_py_commons.schemas.camel_case_schema import CamelCaseSchema
3
- from cc_py_commons.carriers.contact_schema import ContactSchema
4
3
  from cc_py_commons.carriers.account_carrier_map import AccountCarrierMap
5
4
  class AccountCarrierMapSchema(CamelCaseSchema):
6
5
  class Meta:
7
6
  unknown = EXCLUDE
8
7
 
9
8
  account_id = fields.Integer()
10
- customer_code = fields.String(allow_none=True)
11
9
  carrier_id = fields.UUID()
12
- status = fields.String(allow_none=True)
13
- warmup_email_sent_at = fields.Date(allow_none=True)
14
- no_dispatch = fields.Boolean(allow_none=True)
15
-
10
+ status = fields.String()
11
+ customer_code = fields.String(allow_none=True, missing=None)
12
+ warmup_email_sent_at = fields.Date(allow_none=True, missing=None)
13
+ no_dispatch = fields.Boolean(allow_none=True, missing=None)
14
+
16
15
  @post_load
17
- def make_bid(self, data, **kwargs):
16
+ def make_account_carrier_map(self, data, **kwargs):
18
17
  return AccountCarrierMap(**data)
@@ -63,7 +63,7 @@ class CarrierSchema(CamelCaseSchema):
63
63
  vetting_overall_display = fields.String(allow_none=True)
64
64
  last_vetting_time = fields.Date(allow_none=True)
65
65
  vetting_remarks = fields.String(allow_none=True)
66
-
66
+
67
67
  @post_load
68
- def make_bid(self, data, **kwargs):
68
+ def make_carrier(self, data, **kwargs):
69
69
  return Carrier(**data)
@@ -33,6 +33,8 @@ class Config(object):
33
33
  BOOKING_ASSISTANT_SNS_TOPIC_ARN = 'arn:aws:sns:us-west-1:791608169866:booking-assistant-flow-test'
34
34
  BOOKING_ASSISTANT_SNS_SUBJECT = 'booking-assistant-flow'
35
35
  BOOKING_ASSISTANT_SNS_CLASS_NAME = 'com.cargochief.sdk.bookingagent.sns.BookingAssistantFlowNotification'
36
+ BOOKING_ASSISTANT_QUOTE_CANCEL_SUBJECT = 'quote-cancelled'
37
+ BOOKING_ASSISTANT_QUOTE_CANCEL_CLASS_NAME = 'com.cargochief.sdk.bookingagent.sns.QuoteCancelNotification'
36
38
  IMPORT_MOVEMENTS_SNS_TOPIC_ARN = 'arn:aws:sns:us-west-1:791608169866:mcleod-import-movements-test'
37
39
  IMPORT_MOVEMENTS_SNS_SUBJECT = 'import-movements'
38
40
  IMPORT_MOVEMENTS_SNS_CLASS_NAME = 'com.cargochief.sdk.c4.sns.mcleod.ImportMovementsNotification'
@@ -58,6 +60,8 @@ class Config(object):
58
60
  HERMES_SNS_ARN = 'arn:aws:sns:us-west-1:791608169866:hermes-sns-test'
59
61
  C4_ACCOUNTS_BUCKET = 'c4-accounts-test'
60
62
  ANALYTICS_SNS_ARN = 'arn:aws:sns:us-west-1:791608169866:analytics-test'
63
+ WEB_SOCKET_SNS_TOPIC_ARN = 'arn:aws:sns:us-west-1:791608169866:websocket-dev'
64
+ WEB_SOCKET_AUTH_TOKEN = os.getenv('WEB_SOCKET_AUTH_TOKEN')
61
65
 
62
66
  # Database
63
67
  DB_USERNAME = os.getenv('DB_USERNAME')
@@ -117,6 +121,7 @@ class ProductionConfig(Config):
117
121
  HERMES_SNS_ARN = 'arn:aws:sns:us-west-1:791608169866:hermes-sns-prod'
118
122
  C4_ACCOUNTS_BUCKET = 'c4-accounts-prod'
119
123
  ANALYTICS_SNS_ARN ='arn:aws:sns:us-west-1:791608169866:analytics-prod'
124
+ WEB_SOCKET_SNS_TOPIC_ARN = 'arn:aws:sns:us-west-1:791608169866:websocket-prod'
120
125
 
121
126
  config_options = {
122
127
  'local': LocalConfig,
@@ -0,0 +1,3 @@
1
+ class WebSocketAction:
2
+ BROADCAST_TO_USER = 'broadcastActionToUser'
3
+ BROADCAST_TO_ACCOUNT = 'broadcastActionToAccount'
@@ -75,29 +75,34 @@ def get_location_with_country(city, state, zipcode, country, logger, reset_cache
75
75
 
76
76
  return data
77
77
 
78
- def get_distance(origin_latitude, origin_longitude, destination_latitude, destination_longitude, logger):
78
+ def get_distance(origin_latitude, origin_longitude, destination_latitude, destination_longitude, logger, with_duration=False):
79
79
  if not origin_latitude or not origin_longitude or \
80
80
  not destination_latitude or not destination_longitude:
81
81
  raise Exception("Calculating distance requires both origin and destination lat/lng")
82
82
 
83
83
  from_cache = False
84
- pc_miler_can_be_called = False
85
84
  distance_cache_key = __get_distance_cache_key(origin_latitude, origin_longitude, destination_latitude, destination_longitude)
86
- distance = __get_distance_from_cache(distance_cache_key, logger)
85
+ distance_data_dict = __get_distance_from_cache(distance_cache_key, logger)
87
86
 
88
- if distance:
87
+ if distance_data_dict:
89
88
  from_cache = True
90
89
 
91
- if not distance:
92
- distance = __get_google_distance(origin_latitude, origin_longitude, destination_latitude, destination_longitude, logger)
90
+ missing_duration_and_is_required = (with_duration and not distance_data_dict.get('duration'))
91
+ if not distance_data_dict or missing_duration_and_is_required:
92
+ distance_data_dict = __get_google_distance(origin_latitude, origin_longitude, destination_latitude, destination_longitude, logger)
93
93
 
94
- if distance:
95
- if not from_cache:
96
- __cache_distance(distance_cache_key, distance, logger)
94
+ if distance_data_dict:
95
+ if not from_cache or missing_duration_and_is_required:
96
+ __cache_distance(distance_cache_key, distance_data_dict, logger)
97
97
  else:
98
98
  logger.debug(f"geolocate.get_distance - Google returned no result for {distance_cache_key}")
99
99
 
100
- return distance
100
+ if distance_data_dict:
101
+ if with_duration:
102
+ return distance_data_dict
103
+ else:
104
+ return distance_data_dict.get('distance')
105
+ return None
101
106
 
102
107
  def get_timezone(lat,lng, logger):
103
108
  from_cache = False
@@ -124,7 +129,7 @@ def get_timezone(lat,lng, logger):
124
129
  return timezone
125
130
 
126
131
  def __get_google_distance(origin_latitude, origin_longitude, destination_latitude, destination_longitude, logger):
127
- distance = None
132
+ distance_data = None
128
133
  try:
129
134
  gmaps = googlemaps.Client(key=app_config.GOOGLE_API_KEY)
130
135
  origins = [f'{origin_latitude} {origin_longitude}']
@@ -137,10 +142,16 @@ def __get_google_distance(origin_latitude, origin_longitude, destination_latitud
137
142
  if response and response['rows'][0]['elements'][0].get('distance', None):
138
143
  distance_in_meters = response['rows'][0]['elements'][0]['distance']['value']
139
144
  distance = distance_in_meters / 1609
145
+ duration_seconds = response['rows'][0]['elements'][0]['duration']['value']
146
+ duration_minutes = duration_seconds / 60
147
+ distance_data = {
148
+ 'distance': distance,
149
+ 'duration': duration_minutes
150
+ }
140
151
  except Exception as e:
141
152
  logger.error("geolocate.__get_google_distance: Error while getting distance from google", e)
142
- distance = None
143
- return distance
153
+ distance_data = None
154
+ return distance_data
144
155
 
145
156
  def __get_google_location(city, state, zipcode, country, logger):
146
157
  try:
@@ -185,8 +196,7 @@ def __get_google_location(city, state, zipcode, country, logger):
185
196
  logger.warning(f"Cannot select a single address from multiple for {loc_str}.")
186
197
  return None
187
198
  response = [selected_address]
188
- data = __parse_response(response, city)
189
- return data
199
+ return __parse_response(response, city)
190
200
  except googlemaps.exceptions.Timeout as e:
191
201
  msg = "geolocate.__get_google_location - Location lookup timed out {0}, {1}, {2}: {3}".format(city, state, zipcode, e)
192
202
 
@@ -351,19 +361,22 @@ def __get_location_string(city, state, zipcode):
351
361
 
352
362
  return location_string.lower()
353
363
 
354
- def __cache_distance(distance_cache_key, distance, logger):
355
- distance_db_conn.set(distance_cache_key, distance)
364
+ def __cache_distance(distance_cache_key, distance_data, logger):
365
+ distance_db_conn.set(distance_cache_key, str(distance_data))
356
366
 
357
367
  def __get_distance_from_cache(distance_cache_key, logger):
358
- distance = None
368
+ distance_data = {}
359
369
  try:
360
- distance = distance_db_conn.get(distance_cache_key)
361
- if distance:
362
- distance = float(distance)
370
+ cached_data = distance_db_conn.get(distance_cache_key)
371
+ if cached_data:
372
+ if 'duration' in str(cached_data):
373
+ distance_data = literal_eval(cached_data.decode('utf-8'))
374
+ else:
375
+ distance_data['distance'] = float(cached_data)
363
376
  except Exception as e:
364
377
  logger.warn("geolocate.__get_distance_from_cache: Error while getting distance from cache", e)
365
- distance = None
366
- return distance
378
+ distance_data = {}
379
+ return distance_data
367
380
 
368
381
  def __get_distance_cache_key(origin_latitude, origin_longitude, destination_latitude, destination_longitude):
369
382
  return f'{__truncate(origin_latitude)},{__truncate(origin_longitude)}->{__truncate(destination_latitude)},{__truncate(destination_longitude)}'
@@ -0,0 +1,16 @@
1
+ from marshmallow import fields, EXCLUDE, post_load
2
+ from cc_py_commons.schemas.camel_case_schema import CamelCaseSchema
3
+ from cc_py_commons.loads.equipment import Equipment
4
+
5
+ class EquipmentSchema(CamelCaseSchema):
6
+ class Meta:
7
+ unknown = EXCLUDE
8
+
9
+ id = fields.UUID()
10
+ name = fields.String()
11
+ active = fields.Boolean(default=True) # Match the dataclass default
12
+
13
+ @post_load
14
+ def make_equipment(self, data, **kwargs):
15
+ return Equipment(**data)
16
+
@@ -81,3 +81,4 @@ class Load:
81
81
  customer_code: str = field(default=None)
82
82
  ltl: bool = field(default=False)
83
83
  request_id: uuid.UUID = field(default=None)
84
+ predicted_price: int = field(default=None)
@@ -76,6 +76,7 @@ class LoadSchema(CamelCaseSchema):
76
76
  ltl = fields.Boolean(allow_none=True, default=False, missing=False)
77
77
  special_instructions = fields.String(allow_none=True)
78
78
  request_id = fields.UUID(allow_none=True)
79
+ predicted_price: int = fields.Integer(allow_none=True)
79
80
 
80
81
  @post_load
81
82
  def make_load(self, data, **kwargs):
@@ -0,0 +1,19 @@
1
+ import requests
2
+
3
+ from cc_py_commons.utils import json_logger
4
+ from .constants import BOOKING_AGENT_TOKEN, BOOKING_AGENT_URL
5
+
6
+
7
+ def execute(load_id):
8
+ url = f"{BOOKING_AGENT_URL}/quote/by/loadId/{load_id}"
9
+ booking_agent_headers = {
10
+ "Authorization": f"Bearer {BOOKING_AGENT_TOKEN}",
11
+ "Content-Type": "application/json"
12
+ }
13
+ response = requests.get(url, headers=booking_agent_headers)
14
+ if response.status_code == 200:
15
+ return response.json()
16
+ else:
17
+ json_logger.warning(None, 'Failed to get quote from Booking Agent',
18
+ status_code=response.status_code, load_id=str(load_id))
19
+ return None
@@ -0,0 +1,33 @@
1
+ import os
2
+
3
+ import requests
4
+ from dateutil.parser import parse
5
+
6
+ from cc_py_commons.bids.bid_schema import BidSchema
7
+ from cc_py_commons.utils import json_logger
8
+
9
+ BOOKING_AGENT_URL = os.environ.get('BOOKING_AGENT_URL')
10
+ BOOKING_AGENT_TOKEN = os.environ.get("BOOKING_AGENT_TOKEN")
11
+
12
+
13
+ def execute(account_id, filters_dict):
14
+ url = f"{BOOKING_AGENT_URL}/bid/match"
15
+ token = f"Bearer {BOOKING_AGENT_TOKEN}"
16
+ headers = {
17
+ "Authorization": token
18
+ }
19
+ json_logger.debug(account_id, f"Requesting bids from booking-agent", url=url, filters=filters_dict)
20
+ response = requests.get(url, headers=headers, params=filters_dict)
21
+ bids = []
22
+ if response.status_code == 200:
23
+ bids = response.json()['content']
24
+ for bid in bids:
25
+ bid['pickupDate'] = parse(bid['pickupDate']).strftime('%Y-%m-%d')
26
+ bid['deliveryDate'] = parse(bid['deliveryDate']).strftime('%Y-%m-%d')
27
+ if bid.get('inviteEmailedAt'):
28
+ bid['inviteEmailedAt'] = parse(bid['inviteEmailedAt']).isoformat()
29
+ for bid_history in bid.get('bidHistories', []):
30
+ bid_history['pickupDate'] = parse(bid_history['pickupDate']).strftime('%Y-%m-%d')
31
+ bid_history['deliveryDate'] = parse(bid_history['deliveryDate']).strftime('%Y-%m-%d')
32
+ bids = BidSchema().load(bids, many=True)
33
+ return bids
@@ -0,0 +1,27 @@
1
+ import requests
2
+ import os
3
+ from dateutil.parser import parse
4
+
5
+ from cc_py_commons.utils import json_logger
6
+ from cc_py_commons.quotes.quote_schema import QuoteSchema
7
+
8
+ BOOKING_AGENT_URL = os.environ.get('BOOKING_AGENT_URL')
9
+ BOOKING_AGENT_TOKEN = os.environ.get("BOOKING_AGENT_TOKEN")
10
+
11
+
12
+ def execute(account_id, filters_dict):
13
+ url = f"{BOOKING_AGENT_URL}/quote"
14
+ token = f"Bearer {BOOKING_AGENT_TOKEN}"
15
+ headers = {
16
+ "Authorization": token
17
+ }
18
+ json_logger.debug(account_id, f"Requesting quotes from booking-agent", url=url, filters=filters_dict)
19
+ response = requests.get(url, headers=headers, params=filters_dict)
20
+ quotes = []
21
+ if response.status_code == 200:
22
+ quotes = response.json()['content']
23
+ for quote in quotes:
24
+ quote['pickupDate'] = parse(quote['pickupDate']).strftime('%Y-%m-%d')
25
+ quote['deliveryDate'] = parse(quote['deliveryDate']).strftime('%Y-%m-%d')
26
+ quotes = QuoteSchema().load(quotes, many=True)
27
+ return quotes
@@ -0,0 +1,27 @@
1
+ import requests
2
+
3
+ from cc_py_commons.utils import json_logger
4
+ from .constants import C4_API_AUTH_TOKEN, C4_API_URL
5
+ from . import get_account
6
+
7
+
8
+ def by_user_id(user_id):
9
+ url = f"{C4_API_URL}/user/{user_id}/accountSettings"
10
+ token = f"Bearer {C4_API_AUTH_TOKEN}"
11
+ headers = {
12
+ "Authorization": token
13
+ }
14
+ json_logger.debug(None, 'Getting account settings', url=url, headers=headers)
15
+ response = requests.get(url, headers=headers)
16
+ if response.status_code != 200:
17
+ json_logger.warning(None, 'Request to get account settings failed', status_code=response.status_code)
18
+ return None
19
+ return response.json().get('data')
20
+
21
+
22
+ def by_account_id(account_id):
23
+ account = get_account.execute(account_id)
24
+ if account:
25
+ return account.get('accountSettings')
26
+ else:
27
+ return None
@@ -0,0 +1,38 @@
1
+ import json
2
+ import traceback
3
+
4
+ from cc_py_commons.config.env import app_config
5
+ from cc_py_commons.config.web_socket_action import WebSocketAction
6
+ from cc_py_commons.sns.sns_service import SnsService
7
+ from cc_py_commons.utils import json_logger
8
+
9
+
10
+ def execute(action, user_id, account_id, payload):
11
+ if not action or not account_id or not payload:
12
+ json_logger.warning(account_id, 'Missing required parameters')
13
+ return None
14
+ valid_actions = [WebSocketAction.BROADCAST_TO_USER, WebSocketAction.BROADCAST_TO_ACCOUNT]
15
+ if action not in valid_actions:
16
+ json_logger.warning(account_id, f'Invalid action. Should be one of {valid_actions}')
17
+ return None
18
+ web_socket_auth_token = app_config.WEB_SOCKET_AUTH_TOKEN
19
+ if not web_socket_auth_token:
20
+ json_logger.warning(account_id, 'Missing WEB_SOCKET_AUTH_TOKEN')
21
+ return None
22
+ try:
23
+ message = {
24
+ 'authKey': web_socket_auth_token,
25
+ 'action': action,
26
+ 'userId': user_id,
27
+ 'accountId': account_id,
28
+ 'payload': payload
29
+ }
30
+ sns_service = SnsService()
31
+ sns_service.send(app_config.WEB_SOCKET_SNS_TOPIC_ARN, 'web-socket-message', json.dumps(message))
32
+ successful_message = 'Successfully sent the notification'
33
+ json_logger.info(account_id, successful_message)
34
+ return successful_message
35
+ except Exception as e:
36
+ json_logger.error(account_id, 'Failed to send web socket notification', error=str(e),
37
+ stacktrace=traceback.format_exc())
38
+ return None
@@ -0,0 +1,31 @@
1
+ import json
2
+ import traceback
3
+
4
+ from cc_py_commons.config.env import app_config
5
+ from cc_py_commons.sqs.sqs_service import SqsService
6
+ from cc_py_commons.utils.logger_v2 import logger
7
+
8
+ class BookingAssistantQuoteCancelNotification:
9
+
10
+ def send(self, load_id):
11
+ '''
12
+ Sends and event to the Booking Assistant Flow SQS queue specified in the config.
13
+ Returns the messageId of the enqueued message for later retrieval.
14
+ '''
15
+ event = {
16
+ 'loadId': str(load_id),
17
+ 'subject': app_config.BOOKING_ASSISTANT_QUOTE_CANCEL_SUBJECT,
18
+ 'className': app_config.BOOKING_ASSISTANT_QUOTE_CANCEL_CLASS_NAME
19
+ }
20
+ logger.debug(f"sending event {event} to {app_config.BOOKING_ASSISTANT_FLOW_QUEUE}")
21
+
22
+ try:
23
+ sqs_service = SqsService()
24
+ return sqs_service.send(app_config.BOOKING_ASSISTANT_FLOW_QUEUE, json.dumps(event), app_config.BOOKING_ASSISTANT_DELAY_SECONDS)
25
+ except Exception as e:
26
+ logger.error(json.dumps({
27
+ 'message': 'Failed to send class BookingAssistantQuoteCancelNotification',
28
+ 'error': str(e),
29
+ 'sta_cktrace': traceback.format_exc(),
30
+ 'event': event
31
+ }))
@@ -6,7 +6,7 @@ from cc_py_commons.utils.logger_v2 import logger
6
6
 
7
7
  class BookingAssistantFlowEvent:
8
8
 
9
- def send(self, user_id, load, params, capacity_search_equipments, request_id):
9
+ def send(self, user_id, load, params, capacity_search_equipments, request_id, auto_invite_details=None):
10
10
  '''
11
11
  Sends and event to the Booking Assistant Flow SQS queue specified in the config.
12
12
  Returns the messageId of the enqueued message for later retrieval.
@@ -18,7 +18,8 @@ class BookingAssistantFlowEvent:
18
18
  'capacitySearchEquipments': capacity_search_equipments,
19
19
  'requestId': request_id,
20
20
  'subject': f'{app_config.BOOKING_ASSISTANT_SNS_SUBJECT}',
21
- 'className': f'{app_config.BOOKING_ASSISTANT_SNS_CLASS_NAME}'
21
+ 'className': f'{app_config.BOOKING_ASSISTANT_SNS_CLASS_NAME}',
22
+ 'autoInviteDetails': auto_invite_details
22
23
  }
23
24
  logger.debug(f"sending event {event} to {app_config.BOOKING_ASSISTANT_FLOW_QUEUE}")
24
25
 
@@ -0,0 +1,86 @@
1
+ import json
2
+ from uuid import uuid4
3
+ import boto3
4
+
5
+ class SqsService:
6
+ def send(self, queue_url, message, delaySeconds=0, messageGroupId=None):
7
+ '''
8
+ Sends a message to the specified queue and returns the messageId.
9
+ The messageId can be used to lookup and delete the message in the queue.
10
+ '''
11
+ sqs = boto3.client('sqs')
12
+ if messageGroupId:
13
+ response = sqs.send_message(
14
+ QueueUrl=queue_url,
15
+ MessageBody=message,
16
+ DelaySeconds=delaySeconds,
17
+ MessageAttributes={},
18
+ MessageGroupId=messageGroupId
19
+ )
20
+ else:
21
+ response = sqs.send_message(
22
+ QueueUrl=queue_url,
23
+ MessageBody=message,
24
+ DelaySeconds=delaySeconds,
25
+ MessageAttributes={}
26
+ )
27
+ return response.get('MessageId')
28
+
29
+ def send_batches(self, queue_url, messages):
30
+ '''
31
+ Sends all messages to the specified queue in groups of 10 (the limit of send_batch)
32
+ The messageId can be used to lookup and delete the message in the queue.
33
+ Args:
34
+ queue_url (str): The URL of the Amazon SQS queue
35
+ messages (list): List of messages to be sent
36
+
37
+ Returns:
38
+ dict: Results containing 'successful' and 'failed' message lists
39
+ '''
40
+ results = {
41
+ 'successful': [],
42
+ 'failed': []
43
+ }
44
+
45
+ if not messages:
46
+ return results
47
+
48
+ sqs = boto3.client('sqs')
49
+ entries = [
50
+ {
51
+ # each message must have a unique id
52
+ 'Id': str(uuid4()),
53
+ 'MessageBody': json.dumps(message),
54
+ }
55
+ for message in messages
56
+ ]
57
+
58
+ # SQS can only process 10 messages per batch
59
+ batch_size = 10
60
+
61
+ # Split messages into batches of 10
62
+ for i in range(0, len(entries), batch_size):
63
+ batch = entries[i:i + batch_size]
64
+
65
+ try:
66
+ response = sqs.send_message_batch(
67
+ QueueUrl=queue_url,
68
+ Entries=batch
69
+ )
70
+
71
+ # Track successful and failed messages
72
+ if 'Successful' in response:
73
+ results['successful'].extend(response['Successful'])
74
+ if 'Failed' in response:
75
+ results['failed'].extend(response['Failed'])
76
+
77
+ except Exception as e:
78
+ # Mark all messages in failed batch
79
+ failed_batch = [{
80
+ 'Id': entry['Id'],
81
+ 'Error': str(e),
82
+ 'Message': entry['MessageBody']
83
+ } for entry in batch]
84
+ results['failed'].extend(failed_batch)
85
+
86
+ return results
@@ -61,3 +61,4 @@ class TestMapTransaction(unittest.TestCase):
61
61
  t = from_load(self.valid_load)
62
62
  self.assertEqual(self.valid_load.reference_number, t.reference_number)
63
63
  self.assertEqual(self.valid_load.request_id, t.request_id)
64
+ self.assertEqual(self.valid_load.customer_id, t.user_id)
@@ -0,0 +1,39 @@
1
+ from unittest import TestCase
2
+ from unittest.mock import patch
3
+
4
+ from cc_py_commons.config.web_socket_action import WebSocketAction
5
+ from cc_py_commons.services.web_socket import send_notification
6
+ from cc_py_commons.sns.sns_service import SnsService
7
+
8
+
9
+ @patch.object(SnsService, 'send')
10
+ class TestSendNotification(TestCase):
11
+
12
+ def test_when_required_parameters_are_missing(self, sns_service_send):
13
+ result = send_notification.execute(WebSocketAction.BROADCAST_TO_ACCOUNT,
14
+ None, None, {'message': 'test'})
15
+
16
+ self.assertIsNone(result)
17
+ sns_service_send.assert_not_called()
18
+
19
+ def test_invalid_action(self, sns_service_send):
20
+ result = send_notification.execute('INVALID_ACTION',
21
+ None, 1234, {'message': 'test'})
22
+
23
+ self.assertIsNone(result)
24
+ sns_service_send.assert_not_called()
25
+
26
+ def test_when_web_socket_token_is_missing(self, sns_service_send):
27
+ result = send_notification.execute(WebSocketAction.BROADCAST_TO_ACCOUNT,
28
+ None, 1234, {'message': 'test'})
29
+
30
+ self.assertIsNone(result)
31
+ sns_service_send.assert_not_called()
32
+
33
+ @patch('cc_py_commons.config.env.app_config.WEB_SOCKET_AUTH_TOKEN', 'TOKEN')
34
+ def test_valid_request(self, sns_service_send):
35
+ result = send_notification.execute(WebSocketAction.BROADCAST_TO_ACCOUNT,
36
+ None, 1234, {'message': 'test'})
37
+
38
+ self.assertIsNotNone(result)
39
+ sns_service_send.assert_called_once()
@@ -60,6 +60,7 @@ def from_load(load):
60
60
  trans_data['pickup_close_time'] = load.pickup_close_time
61
61
  trans_data['freight_hub_load_id'] = load.id
62
62
  trans_data['revenue_code'] = load.revenue_code
63
+ trans_data['user_id'] = load.customer_id
63
64
  if load.special_instructions:
64
65
  trans_data['comments'] = load.special_instructions
65
66
  if load.linear_feet:
@@ -109,3 +109,4 @@ class Transaction:
109
109
  ltl: bool = field(default=False)
110
110
  revenue_code: str = field(default=None)
111
111
  request_id: uuid.UUID = field(default=None)
112
+ user_id: int = field(default=None)
@@ -106,6 +106,7 @@ class TransactionSchema(CamelCaseSchema):
106
106
  revenue_code = fields.String(allow_none=True)
107
107
  request_id = fields.UUID(allow_none=True)
108
108
  mcleod_movement_id = fields.String(allow_none=True)
109
+ user_id = fields.Integer(allow_none=True)
109
110
 
110
111
  @post_load
111
112
  def classify(self, data, **kwargs):
File without changes
@@ -1,3 +1,6 @@
1
1
  def get_table_name(bulk_search_id):
2
+ """
3
+ SHOULD NOT BE USED GOING FORWARD. Restoring for mercury dependency until all code is released.
4
+ """
2
5
  bulk_search_id_string = str(bulk_search_id).replace('-', '')
3
6
  return f'bulk_lane_pricing_results_{bulk_search_id_string}'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cc-py-commons
3
- Version: 0.5.15
3
+ Version: 0.5.35
4
4
  Summary: Common code for microservices
5
5
  Home-page: https://github.com/Cargo-Chief/py-commons
6
6
  Author: CargoChief