|
1 | 1 | import json |
2 | 2 | import logging |
3 | 3 |
|
4 | | -from mip_api import chart, s3, ssm, upstream, util |
| 4 | +from mip_api import balances, chart, s3, ssm, upstream, util |
5 | 5 |
|
6 | 6 |
|
7 | 7 | LOG = logging.getLogger(__name__) |
@@ -30,68 +30,118 @@ def lambda_handler(event, context): |
30 | 30 | Return doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html |
31 | 31 | """ |
32 | 32 |
|
33 | | - # helper functions to encapsulate the body, headers, and status code |
34 | | - def _build_return(code, body): |
35 | | - return { |
36 | | - "statusCode": code, |
37 | | - "body": json.dumps(body, indent=2), |
38 | | - } |
39 | | - |
40 | 33 | try: |
41 | 34 | # collect environment variables |
42 | | - mip_org = util.get_os_var("MipsOrg") |
| 35 | + mip_org = util.get_os_var("MipOrg") |
43 | 36 | ssm_path = util.get_os_var("SsmPath") |
44 | 37 | s3_bucket = util.get_os_var("CacheBucket") |
45 | | - s3_path = util.get_os_var("CacheBucketPath") |
| 38 | + s3_prefix = util.get_os_var("CacheBucketPrefix") |
46 | 39 |
|
47 | 40 | code_other = util.get_os_var("OtherCode") |
48 | 41 | code_no_program = util.get_os_var("NoProgramCode") |
49 | 42 |
|
50 | 43 | api_routes = { |
51 | 44 | "ApiChartOfAccounts": util.get_os_var("ApiChartOfAccounts"), |
52 | 45 | "ApiValidTags": util.get_os_var("ApiValidTags"), |
| 46 | + "ApiTrialBalances": util.get_os_var("ApiTrialBalances"), |
53 | 47 | } |
54 | 48 |
|
55 | 49 | _to_omit = util.get_os_var("CodesToOmit") |
56 | 50 | omit_codes_list = util.parse_codes(_to_omit) |
57 | 51 |
|
| 52 | + # collect query-string parameters |
| 53 | + params = util.params_dict(event) |
| 54 | + |
| 55 | + # build S3 cache paths, with separate paths for each combination |
| 56 | + # of endpoint and relevant parameters |
| 57 | + s3_path_gl_coa = s3_prefix + "gl-coa" |
| 58 | + if not params["hide_inactive"]: |
| 59 | + s3_path_gl_coa += "-full" |
| 60 | + s3_path_gl_coa += ".json" |
| 61 | + |
| 62 | + s3_path_program_coa = s3_prefix + "program-coa" |
| 63 | + if not params["hide_inactive"]: |
| 64 | + s3_path_program_coa += "-full" |
| 65 | + s3_path_program_coa += ".json" |
| 66 | + |
| 67 | + s3_path_balances = s3_prefix + "balances" |
| 68 | + if not params["hide_inactive"]: |
| 69 | + s3_path_balances += "-full" |
| 70 | + if not params["ytd"]: |
| 71 | + s3_path_balances += "-ytd" |
| 72 | + s3_path_balances += ".json" |
| 73 | + |
58 | 74 | # get secure parameters |
59 | 75 | ssm_secrets = ssm.get_secrets(ssm_path) |
60 | 76 |
|
61 | | - # get chart of accounts from mip cloud |
62 | | - raw_chart = chart.get_chart(mip_org, ssm_secrets, s3_bucket, s3_path) |
63 | | - LOG.debug(f"Raw chart data: {raw_chart}") |
64 | | - |
65 | | - # collect query-string parameters |
66 | | - params = {} |
67 | | - if "queryStringParameters" in event: |
68 | | - params = event["queryStringParameters"] |
69 | | - LOG.debug(f"Query-string parameters: {params}") |
70 | | - |
71 | 77 | # parse the path and return appropriate data |
72 | 78 | if "path" in event: |
73 | 79 | event_path = event["path"] |
74 | 80 |
|
75 | | - # always process the chart of accounts |
76 | | - mip_chart = chart.process_chart( |
77 | | - params, raw_chart, omit_codes_list, code_other, code_no_program |
78 | | - ) |
| 81 | + if event_path == api_routes["ApiTrialBalances"]: |
| 82 | + # get chart of GL accounts |
| 83 | + gl_chart = chart.get_gl_chart( |
| 84 | + mip_org, |
| 85 | + ssm_secrets, |
| 86 | + s3_bucket, |
| 87 | + s3_path_gl_coa, |
| 88 | + params["hide_inactive"], |
| 89 | + ) |
| 90 | + LOG.debug(f"Raw chart data: {gl_chart}") |
| 91 | + |
| 92 | + # get upstream balance data |
| 93 | + raw_bal = balances.get_balances( |
| 94 | + mip_org, |
| 95 | + ssm_secrets, |
| 96 | + s3_bucket, |
| 97 | + s3_path_balances, |
| 98 | + params["ytd"], |
| 99 | + ) |
| 100 | + |
| 101 | + # combine them into CSV output |
| 102 | + balances_csv = balances.format_csv(raw_bal, gl_chart) |
| 103 | + return util.build_return_text(200, balances_csv) |
| 104 | + |
| 105 | + else: # common processing for '/accounts' and '/tags' |
| 106 | + |
| 107 | + # get chart of Program accounts |
| 108 | + _raw_program_chart = chart.get_program_chart( |
| 109 | + mip_org, |
| 110 | + ssm_secrets, |
| 111 | + s3_bucket, |
| 112 | + s3_path_program_coa, |
| 113 | + params["hide_inactive"], |
| 114 | + ) |
| 115 | + LOG.debug(f"Raw chart data: {_raw_program_chart}") |
| 116 | + |
| 117 | + # always process the chart of Program accounts |
| 118 | + _program_chart = chart.process_chart( |
| 119 | + _raw_program_chart, |
| 120 | + omit_codes_list, |
| 121 | + code_other, |
| 122 | + code_no_program, |
| 123 | + params, |
| 124 | + ) |
| 125 | + |
| 126 | + # always limit the size of the chart |
| 127 | + program_chart = chart.limit_chart(_program_chart, params["limit"]) |
79 | 128 |
|
80 | 129 | if event_path == api_routes["ApiChartOfAccounts"]: |
81 | | - # conditionally limit the size of the output |
82 | | - return_chart = chart.limit_chart(params, mip_chart) |
83 | | - return _build_return(200, return_chart) |
| 130 | + # no more processing, return chart |
| 131 | + return util.build_return_json(200, program_chart) |
84 | 132 |
|
85 | 133 | elif event_path == api_routes["ApiValidTags"]: |
86 | 134 | # build a list of strings from the processed dictionary |
87 | | - valid_tags = chart.list_tags(params, mip_chart) |
88 | | - return _build_return(200, valid_tags) |
| 135 | + valid_tags = chart.list_tags(program_chart) |
| 136 | + return util.build_return_json(200, valid_tags) |
89 | 137 |
|
90 | | - else: |
91 | | - return _build_return(404, {"error": "Invalid request path"}) |
| 138 | + else: # unknown API endpoint |
| 139 | + return util.build_return_json(404, {"error": "Invalid request path"}) |
92 | 140 |
|
93 | | - return _build_return(400, {"error": f"Invalid event: No path found: {event}"}) |
| 141 | + return util.build_return_json( |
| 142 | + 400, {"error": f"Invalid event: No path found: {event}"} |
| 143 | + ) |
94 | 144 |
|
95 | 145 | except Exception as exc: |
96 | 146 | LOG.exception(exc) |
97 | | - return _build_return(500, {"error": str(exc)}) |
| 147 | + return util.build_return_json(500, {"error": str(exc)}) |
0 commit comments