sqlite-export-for-ynab 2.1.0__tar.gz → 2.3.0__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.
- {sqlite_export_for_ynab-2.1.0/sqlite_export_for_ynab.egg-info → sqlite_export_for_ynab-2.3.0}/PKG-INFO +151 -37
- {sqlite_export_for_ynab-2.1.0 → sqlite_export_for_ynab-2.3.0}/README.md +150 -36
- {sqlite_export_for_ynab-2.1.0 → sqlite_export_for_ynab-2.3.0}/setup.cfg +1 -1
- {sqlite_export_for_ynab-2.1.0 → sqlite_export_for_ynab-2.3.0}/sqlite_export_for_ynab/_main.py +92 -38
- {sqlite_export_for_ynab-2.1.0 → sqlite_export_for_ynab-2.3.0}/sqlite_export_for_ynab/ddl/create-relations.sql +1 -1
- {sqlite_export_for_ynab-2.1.0 → sqlite_export_for_ynab-2.3.0/sqlite_export_for_ynab.egg-info}/PKG-INFO +151 -37
- {sqlite_export_for_ynab-2.1.0 → sqlite_export_for_ynab-2.3.0}/testing/fixtures.py +6 -4
- {sqlite_export_for_ynab-2.1.0 → sqlite_export_for_ynab-2.3.0}/tests/_main_test.py +89 -16
- {sqlite_export_for_ynab-2.1.0 → sqlite_export_for_ynab-2.3.0}/LICENSE +0 -0
- {sqlite_export_for_ynab-2.1.0 → sqlite_export_for_ynab-2.3.0}/pyproject.toml +0 -0
- {sqlite_export_for_ynab-2.1.0 → sqlite_export_for_ynab-2.3.0}/setup.py +0 -0
- {sqlite_export_for_ynab-2.1.0 → sqlite_export_for_ynab-2.3.0}/sqlite_export_for_ynab/__init__.py +0 -0
- {sqlite_export_for_ynab-2.1.0 → sqlite_export_for_ynab-2.3.0}/sqlite_export_for_ynab/__main__.py +0 -0
- {sqlite_export_for_ynab-2.1.0 → sqlite_export_for_ynab-2.3.0}/sqlite_export_for_ynab/ddl/__init__.py +0 -0
- {sqlite_export_for_ynab-2.1.0 → sqlite_export_for_ynab-2.3.0}/sqlite_export_for_ynab/ddl/drop-relations.sql +0 -0
- {sqlite_export_for_ynab-2.1.0 → sqlite_export_for_ynab-2.3.0}/sqlite_export_for_ynab/py.typed +0 -0
- {sqlite_export_for_ynab-2.1.0 → sqlite_export_for_ynab-2.3.0}/sqlite_export_for_ynab.egg-info/SOURCES.txt +0 -0
- {sqlite_export_for_ynab-2.1.0 → sqlite_export_for_ynab-2.3.0}/sqlite_export_for_ynab.egg-info/dependency_links.txt +0 -0
- {sqlite_export_for_ynab-2.1.0 → sqlite_export_for_ynab-2.3.0}/sqlite_export_for_ynab.egg-info/entry_points.txt +0 -0
- {sqlite_export_for_ynab-2.1.0 → sqlite_export_for_ynab-2.3.0}/sqlite_export_for_ynab.egg-info/requires.txt +0 -0
- {sqlite_export_for_ynab-2.1.0 → sqlite_export_for_ynab-2.3.0}/sqlite_export_for_ynab.egg-info/top_level.txt +0 -0
- {sqlite_export_for_ynab-2.1.0 → sqlite_export_for_ynab-2.3.0}/testing/__init__.py +0 -0
- {sqlite_export_for_ynab-2.1.0 → sqlite_export_for_ynab-2.3.0}/tests/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sqlite_export_for_ynab
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.3.0
|
|
4
4
|
Summary: SQLite Export for YNAB - Export YNAB Data to SQLite
|
|
5
5
|
Home-page: https://github.com/mxr/sqlite-export-for-ynab
|
|
6
6
|
Author: Max R
|
|
@@ -51,6 +51,7 @@ $ sqlite-export-for-ynab
|
|
|
51
51
|
```
|
|
52
52
|
|
|
53
53
|
Running it again will pull only data that changed since the last pull (this is done with [Delta Requests](https://api.ynab.com/#deltas)). If you want to wipe the DB and pull all data again use the `--full-refresh` flag.
|
|
54
|
+
Pass `--quiet` to suppress all CLI output, including progress bars.
|
|
54
55
|
|
|
55
56
|
<a id="db-path"></a>You can specify the DB path with the following options
|
|
56
57
|
1. The `--db` flag.
|
|
@@ -81,7 +82,7 @@ The relations are defined in [create-relations.sql](sqlite_export_for_ynab/ddl/c
|
|
|
81
82
|
|
|
82
83
|
1. Some objects are pulled out into their own tables so they can be more cleanly modeled in SQLite (ex: subtransactions, loan account periodic values).
|
|
83
84
|
1. Foreign keys are added as needed (ex: plan ID, transaction ID) so data across plans remains separate.
|
|
84
|
-
1. Two new views called `flat_transactions` and `scheduled_flat_transactions`. These allow you to query split and non-split transactions easily, without needing to also query `subtransactions` and `scheduled_subtransactions` respectively. They also filter out deleted transactions/subtransactions and project payee/category fields to make querying more ergonomic.
|
|
85
|
+
1. Two new views called `flat_transactions` and `scheduled_flat_transactions`. These allow you to query split and non-split transactions easily, without needing to also query `subtransactions` and `scheduled_subtransactions` respectively. They also filter out deleted/unapproved transactions/subtransactions and project payee/category fields to make querying more ergonomic.
|
|
85
86
|
|
|
86
87
|
## Querying
|
|
87
88
|
|
|
@@ -135,6 +136,7 @@ WITH used_payees AS (
|
|
|
135
136
|
FROM transactions
|
|
136
137
|
WHERE
|
|
137
138
|
TRUE
|
|
139
|
+
AND approved
|
|
138
140
|
AND payee_id IS NOT NULL
|
|
139
141
|
AND NOT deleted
|
|
140
142
|
UNION
|
|
@@ -345,44 +347,80 @@ To compare assigned category values to a given account's balance:
|
|
|
345
347
|
-- -cmd ".parameter set @account_name_like %Savings%" \
|
|
346
348
|
-- -cmd ".parameter set @include_category_groups 'Home,Food'" \
|
|
347
349
|
-- < query.sql
|
|
350
|
+
CREATE TEMP TABLE excess_query_results AS
|
|
348
351
|
WITH params AS (
|
|
349
352
|
SELECT
|
|
350
353
|
TRIM(COALESCE(@account_name_like, '')) AS account_name_like
|
|
354
|
+
, TRIM(COALESCE(@plan_id, '')) AS plan_id
|
|
351
355
|
, TRIM(COALESCE(@include_category_groups, ''))
|
|
352
356
|
AS include_category_groups
|
|
353
357
|
, TRIM(COALESCE(@exclude_category_groups, ''))
|
|
354
358
|
AS exclude_category_groups
|
|
355
359
|
)
|
|
356
360
|
|
|
357
|
-
,
|
|
358
|
-
SELECT
|
|
359
|
-
|
|
360
|
-
|
|
361
|
+
, scoped_plans AS (
|
|
362
|
+
SELECT
|
|
363
|
+
p.id
|
|
364
|
+
, p.name
|
|
365
|
+
FROM plans AS p
|
|
366
|
+
CROSS JOIN params AS prm
|
|
367
|
+
WHERE prm.plan_id = '' OR p.id = prm.plan_id
|
|
368
|
+
)
|
|
369
|
+
|
|
370
|
+
, split_include_category_groups (value, rest) AS (
|
|
371
|
+
SELECT
|
|
372
|
+
''
|
|
373
|
+
, prm.include_category_groups || ','
|
|
374
|
+
FROM params AS prm
|
|
361
375
|
UNION ALL
|
|
362
376
|
SELECT
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
FROM
|
|
366
|
-
WHERE
|
|
377
|
+
TRIM(SUBSTR(rest, 1, INSTR(rest, ',') - 1))
|
|
378
|
+
, SUBSTR(rest, INSTR(rest, ',') + 1)
|
|
379
|
+
FROM split_include_category_groups
|
|
380
|
+
WHERE rest != ''
|
|
367
381
|
)
|
|
368
382
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
383
|
+
, include_category_groups AS (
|
|
384
|
+
SELECT value AS name
|
|
385
|
+
FROM split_include_category_groups
|
|
386
|
+
WHERE value != ''
|
|
387
|
+
)
|
|
373
388
|
|
|
374
|
-
|
|
389
|
+
, split_exclude_category_groups (value, rest) AS (
|
|
375
390
|
SELECT
|
|
376
|
-
|
|
377
|
-
,
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
391
|
+
''
|
|
392
|
+
, prm.exclude_category_groups || ','
|
|
393
|
+
FROM params AS prm
|
|
394
|
+
UNION ALL
|
|
395
|
+
SELECT
|
|
396
|
+
TRIM(SUBSTR(rest, 1, INSTR(rest, ',') - 1))
|
|
397
|
+
, SUBSTR(rest, INSTR(rest, ',') + 1)
|
|
398
|
+
FROM split_exclude_category_groups
|
|
399
|
+
WHERE rest != ''
|
|
400
|
+
)
|
|
401
|
+
|
|
402
|
+
, exclude_category_groups AS (
|
|
403
|
+
SELECT value AS name
|
|
404
|
+
FROM split_exclude_category_groups
|
|
405
|
+
WHERE value != ''
|
|
406
|
+
)
|
|
407
|
+
|
|
408
|
+
, matching_accounts AS (
|
|
409
|
+
SELECT
|
|
410
|
+
sp.id AS plan_id
|
|
411
|
+
, sp.name AS plan_name
|
|
412
|
+
, COUNT(*) AS matches
|
|
413
|
+
FROM scoped_plans AS sp
|
|
414
|
+
INNER JOIN accounts AS a ON sp.id = a.plan_id
|
|
415
|
+
CROSS JOIN params AS prm
|
|
416
|
+
WHERE NOT a.deleted AND a.name LIKE prm.account_name_like
|
|
417
|
+
GROUP BY sp.id, sp.name
|
|
381
418
|
)
|
|
382
419
|
|
|
383
420
|
, validation AS (
|
|
384
421
|
SELECT
|
|
385
422
|
p.account_name_like
|
|
423
|
+
, p.plan_id
|
|
386
424
|
, p.include_category_groups
|
|
387
425
|
, p.exclude_category_groups
|
|
388
426
|
FROM params AS p
|
|
@@ -398,11 +436,62 @@ WITH params AS (
|
|
|
398
436
|
|| ' or @exclude_category_groups' AS error
|
|
399
437
|
FROM validation AS v
|
|
400
438
|
WHERE v.include_category_groups != '' AND v.exclude_category_groups != ''
|
|
439
|
+
UNION ALL
|
|
440
|
+
SELECT 'No plan matched @plan_id' AS error
|
|
441
|
+
FROM validation AS v
|
|
442
|
+
WHERE
|
|
443
|
+
v.plan_id != '' AND NOT EXISTS (
|
|
444
|
+
SELECT 1
|
|
445
|
+
FROM scoped_plans
|
|
446
|
+
)
|
|
447
|
+
UNION ALL
|
|
448
|
+
SELECT 'No account names matched @account_name_like' AS error
|
|
449
|
+
FROM validation AS v
|
|
450
|
+
WHERE
|
|
451
|
+
v.account_name_like != '' AND NOT EXISTS (
|
|
452
|
+
SELECT 1
|
|
453
|
+
FROM matching_accounts
|
|
454
|
+
)
|
|
455
|
+
UNION ALL
|
|
456
|
+
SELECT
|
|
457
|
+
'Matched more than 1 account in plan: '
|
|
458
|
+
|| ma.plan_name AS error
|
|
459
|
+
FROM matching_accounts AS ma
|
|
460
|
+
WHERE ma.matches > 1
|
|
461
|
+
UNION ALL
|
|
462
|
+
SELECT
|
|
463
|
+
'Unknown include category group in plan '
|
|
464
|
+
|| sp.name
|
|
465
|
+
|| ': '
|
|
466
|
+
|| icg.name AS error
|
|
467
|
+
FROM scoped_plans AS sp
|
|
468
|
+
CROSS JOIN include_category_groups AS icg
|
|
469
|
+
LEFT JOIN category_groups AS cg
|
|
470
|
+
ON
|
|
471
|
+
sp.id = cg.plan_id
|
|
472
|
+
AND NOT COALESCE(cg.deleted, 0)
|
|
473
|
+
AND LOWER(cg.name) = LOWER(icg.name)
|
|
474
|
+
WHERE cg.id IS NULL
|
|
475
|
+
UNION ALL
|
|
476
|
+
SELECT
|
|
477
|
+
'Unknown exclude category group in plan '
|
|
478
|
+
|| sp.name
|
|
479
|
+
|| ': '
|
|
480
|
+
|| ecg.name AS error
|
|
481
|
+
FROM scoped_plans AS sp
|
|
482
|
+
CROSS JOIN exclude_category_groups AS ecg
|
|
483
|
+
LEFT JOIN category_groups AS cg
|
|
484
|
+
ON
|
|
485
|
+
sp.id = cg.plan_id
|
|
486
|
+
AND NOT COALESCE(cg.deleted, 0)
|
|
487
|
+
AND LOWER(cg.name) = LOWER(ecg.name)
|
|
488
|
+
WHERE cg.id IS NULL
|
|
401
489
|
)
|
|
402
490
|
|
|
403
491
|
, valid_params AS (
|
|
404
492
|
SELECT
|
|
405
493
|
v.account_name_like
|
|
494
|
+
, v.plan_id
|
|
406
495
|
, v.include_category_groups
|
|
407
496
|
, v.exclude_category_groups
|
|
408
497
|
FROM validation AS v
|
|
@@ -425,7 +514,7 @@ WITH params AS (
|
|
|
425
514
|
TRUE
|
|
426
515
|
AND NOT a.deleted
|
|
427
516
|
AND a.name LIKE v.account_name_like
|
|
428
|
-
AND (
|
|
517
|
+
AND (v.plan_id = '' OR p.id = v.plan_id)
|
|
429
518
|
)
|
|
430
519
|
|
|
431
520
|
, category_totals AS (
|
|
@@ -440,36 +529,61 @@ WITH params AS (
|
|
|
440
529
|
AND c.category_group_name != 'Internal Master Category'
|
|
441
530
|
AND (
|
|
442
531
|
v.include_category_groups = ''
|
|
443
|
-
OR
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
, ',' || LOWER(c.category_group_name) || ','
|
|
532
|
+
OR EXISTS (
|
|
533
|
+
SELECT 1
|
|
534
|
+
FROM include_category_groups AS icg
|
|
535
|
+
WHERE LOWER(icg.name) = LOWER(c.category_group_name)
|
|
448
536
|
)
|
|
449
|
-
> 0
|
|
450
537
|
)
|
|
451
538
|
AND (
|
|
452
539
|
v.exclude_category_groups = ''
|
|
453
|
-
OR
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
, ',' || LOWER(c.category_group_name) || ','
|
|
540
|
+
OR NOT EXISTS (
|
|
541
|
+
SELECT 1
|
|
542
|
+
FROM exclude_category_groups AS ecg
|
|
543
|
+
WHERE LOWER(ecg.name) = LOWER(c.category_group_name)
|
|
458
544
|
)
|
|
459
|
-
= 0
|
|
460
545
|
)
|
|
461
|
-
AND (
|
|
546
|
+
AND (v.plan_id = '' OR c.plan_id = v.plan_id)
|
|
462
547
|
GROUP BY c.plan_id
|
|
463
548
|
)
|
|
464
549
|
|
|
465
550
|
SELECT
|
|
466
|
-
|
|
551
|
+
ve.error AS error_message
|
|
552
|
+
, NULL AS "plan"
|
|
553
|
+
, NULL AS account
|
|
554
|
+
, NULL AS total
|
|
555
|
+
, NULL AS excess
|
|
556
|
+
FROM validation_errors AS ve
|
|
557
|
+
|
|
558
|
+
UNION ALL
|
|
559
|
+
|
|
560
|
+
SELECT
|
|
561
|
+
NULL AS error_message
|
|
562
|
+
, ma.plan_name AS "plan"
|
|
467
563
|
, ma.account_name AS account
|
|
468
564
|
, PRINTF('%.2f', COALESCE(ct.total, 0)) AS total
|
|
469
|
-
, PRINTF('%.2f', COALESCE(ct.total, 0)
|
|
565
|
+
, PRINTF('%.2f', ma.account_amount - COALESCE(ct.total, 0)) AS excess
|
|
470
566
|
FROM matched_accounts AS ma
|
|
471
567
|
LEFT JOIN category_totals AS ct ON ma.plan_id = ct.plan_id
|
|
472
|
-
|
|
568
|
+
;
|
|
569
|
+
|
|
570
|
+
SELECT error_message
|
|
571
|
+
FROM excess_query_results
|
|
572
|
+
WHERE error_message IS NOT NULL
|
|
573
|
+
;
|
|
574
|
+
|
|
575
|
+
SELECT
|
|
576
|
+
eqr."plan"
|
|
577
|
+
, eqr.account
|
|
578
|
+
, eqr.total
|
|
579
|
+
, eqr.excess
|
|
580
|
+
FROM excess_query_results AS eqr
|
|
581
|
+
WHERE
|
|
582
|
+
NOT EXISTS (
|
|
583
|
+
SELECT 1
|
|
584
|
+
FROM excess_query_results AS eqr_errors
|
|
585
|
+
WHERE eqr_errors.error_message IS NOT NULL
|
|
586
|
+
)
|
|
473
587
|
;
|
|
474
588
|
```
|
|
475
589
|
|
|
@@ -31,6 +31,7 @@ $ sqlite-export-for-ynab
|
|
|
31
31
|
```
|
|
32
32
|
|
|
33
33
|
Running it again will pull only data that changed since the last pull (this is done with [Delta Requests](https://api.ynab.com/#deltas)). If you want to wipe the DB and pull all data again use the `--full-refresh` flag.
|
|
34
|
+
Pass `--quiet` to suppress all CLI output, including progress bars.
|
|
34
35
|
|
|
35
36
|
<a id="db-path"></a>You can specify the DB path with the following options
|
|
36
37
|
1. The `--db` flag.
|
|
@@ -61,7 +62,7 @@ The relations are defined in [create-relations.sql](sqlite_export_for_ynab/ddl/c
|
|
|
61
62
|
|
|
62
63
|
1. Some objects are pulled out into their own tables so they can be more cleanly modeled in SQLite (ex: subtransactions, loan account periodic values).
|
|
63
64
|
1. Foreign keys are added as needed (ex: plan ID, transaction ID) so data across plans remains separate.
|
|
64
|
-
1. Two new views called `flat_transactions` and `scheduled_flat_transactions`. These allow you to query split and non-split transactions easily, without needing to also query `subtransactions` and `scheduled_subtransactions` respectively. They also filter out deleted transactions/subtransactions and project payee/category fields to make querying more ergonomic.
|
|
65
|
+
1. Two new views called `flat_transactions` and `scheduled_flat_transactions`. These allow you to query split and non-split transactions easily, without needing to also query `subtransactions` and `scheduled_subtransactions` respectively. They also filter out deleted/unapproved transactions/subtransactions and project payee/category fields to make querying more ergonomic.
|
|
65
66
|
|
|
66
67
|
## Querying
|
|
67
68
|
|
|
@@ -115,6 +116,7 @@ WITH used_payees AS (
|
|
|
115
116
|
FROM transactions
|
|
116
117
|
WHERE
|
|
117
118
|
TRUE
|
|
119
|
+
AND approved
|
|
118
120
|
AND payee_id IS NOT NULL
|
|
119
121
|
AND NOT deleted
|
|
120
122
|
UNION
|
|
@@ -325,44 +327,80 @@ To compare assigned category values to a given account's balance:
|
|
|
325
327
|
-- -cmd ".parameter set @account_name_like %Savings%" \
|
|
326
328
|
-- -cmd ".parameter set @include_category_groups 'Home,Food'" \
|
|
327
329
|
-- < query.sql
|
|
330
|
+
CREATE TEMP TABLE excess_query_results AS
|
|
328
331
|
WITH params AS (
|
|
329
332
|
SELECT
|
|
330
333
|
TRIM(COALESCE(@account_name_like, '')) AS account_name_like
|
|
334
|
+
, TRIM(COALESCE(@plan_id, '')) AS plan_id
|
|
331
335
|
, TRIM(COALESCE(@include_category_groups, ''))
|
|
332
336
|
AS include_category_groups
|
|
333
337
|
, TRIM(COALESCE(@exclude_category_groups, ''))
|
|
334
338
|
AS exclude_category_groups
|
|
335
339
|
)
|
|
336
340
|
|
|
337
|
-
,
|
|
338
|
-
SELECT
|
|
339
|
-
|
|
340
|
-
|
|
341
|
+
, scoped_plans AS (
|
|
342
|
+
SELECT
|
|
343
|
+
p.id
|
|
344
|
+
, p.name
|
|
345
|
+
FROM plans AS p
|
|
346
|
+
CROSS JOIN params AS prm
|
|
347
|
+
WHERE prm.plan_id = '' OR p.id = prm.plan_id
|
|
348
|
+
)
|
|
349
|
+
|
|
350
|
+
, split_include_category_groups (value, rest) AS (
|
|
351
|
+
SELECT
|
|
352
|
+
''
|
|
353
|
+
, prm.include_category_groups || ','
|
|
354
|
+
FROM params AS prm
|
|
341
355
|
UNION ALL
|
|
342
356
|
SELECT
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
FROM
|
|
346
|
-
WHERE
|
|
357
|
+
TRIM(SUBSTR(rest, 1, INSTR(rest, ',') - 1))
|
|
358
|
+
, SUBSTR(rest, INSTR(rest, ',') + 1)
|
|
359
|
+
FROM split_include_category_groups
|
|
360
|
+
WHERE rest != ''
|
|
347
361
|
)
|
|
348
362
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
363
|
+
, include_category_groups AS (
|
|
364
|
+
SELECT value AS name
|
|
365
|
+
FROM split_include_category_groups
|
|
366
|
+
WHERE value != ''
|
|
367
|
+
)
|
|
353
368
|
|
|
354
|
-
|
|
369
|
+
, split_exclude_category_groups (value, rest) AS (
|
|
355
370
|
SELECT
|
|
356
|
-
|
|
357
|
-
,
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
371
|
+
''
|
|
372
|
+
, prm.exclude_category_groups || ','
|
|
373
|
+
FROM params AS prm
|
|
374
|
+
UNION ALL
|
|
375
|
+
SELECT
|
|
376
|
+
TRIM(SUBSTR(rest, 1, INSTR(rest, ',') - 1))
|
|
377
|
+
, SUBSTR(rest, INSTR(rest, ',') + 1)
|
|
378
|
+
FROM split_exclude_category_groups
|
|
379
|
+
WHERE rest != ''
|
|
380
|
+
)
|
|
381
|
+
|
|
382
|
+
, exclude_category_groups AS (
|
|
383
|
+
SELECT value AS name
|
|
384
|
+
FROM split_exclude_category_groups
|
|
385
|
+
WHERE value != ''
|
|
386
|
+
)
|
|
387
|
+
|
|
388
|
+
, matching_accounts AS (
|
|
389
|
+
SELECT
|
|
390
|
+
sp.id AS plan_id
|
|
391
|
+
, sp.name AS plan_name
|
|
392
|
+
, COUNT(*) AS matches
|
|
393
|
+
FROM scoped_plans AS sp
|
|
394
|
+
INNER JOIN accounts AS a ON sp.id = a.plan_id
|
|
395
|
+
CROSS JOIN params AS prm
|
|
396
|
+
WHERE NOT a.deleted AND a.name LIKE prm.account_name_like
|
|
397
|
+
GROUP BY sp.id, sp.name
|
|
361
398
|
)
|
|
362
399
|
|
|
363
400
|
, validation AS (
|
|
364
401
|
SELECT
|
|
365
402
|
p.account_name_like
|
|
403
|
+
, p.plan_id
|
|
366
404
|
, p.include_category_groups
|
|
367
405
|
, p.exclude_category_groups
|
|
368
406
|
FROM params AS p
|
|
@@ -378,11 +416,62 @@ WITH params AS (
|
|
|
378
416
|
|| ' or @exclude_category_groups' AS error
|
|
379
417
|
FROM validation AS v
|
|
380
418
|
WHERE v.include_category_groups != '' AND v.exclude_category_groups != ''
|
|
419
|
+
UNION ALL
|
|
420
|
+
SELECT 'No plan matched @plan_id' AS error
|
|
421
|
+
FROM validation AS v
|
|
422
|
+
WHERE
|
|
423
|
+
v.plan_id != '' AND NOT EXISTS (
|
|
424
|
+
SELECT 1
|
|
425
|
+
FROM scoped_plans
|
|
426
|
+
)
|
|
427
|
+
UNION ALL
|
|
428
|
+
SELECT 'No account names matched @account_name_like' AS error
|
|
429
|
+
FROM validation AS v
|
|
430
|
+
WHERE
|
|
431
|
+
v.account_name_like != '' AND NOT EXISTS (
|
|
432
|
+
SELECT 1
|
|
433
|
+
FROM matching_accounts
|
|
434
|
+
)
|
|
435
|
+
UNION ALL
|
|
436
|
+
SELECT
|
|
437
|
+
'Matched more than 1 account in plan: '
|
|
438
|
+
|| ma.plan_name AS error
|
|
439
|
+
FROM matching_accounts AS ma
|
|
440
|
+
WHERE ma.matches > 1
|
|
441
|
+
UNION ALL
|
|
442
|
+
SELECT
|
|
443
|
+
'Unknown include category group in plan '
|
|
444
|
+
|| sp.name
|
|
445
|
+
|| ': '
|
|
446
|
+
|| icg.name AS error
|
|
447
|
+
FROM scoped_plans AS sp
|
|
448
|
+
CROSS JOIN include_category_groups AS icg
|
|
449
|
+
LEFT JOIN category_groups AS cg
|
|
450
|
+
ON
|
|
451
|
+
sp.id = cg.plan_id
|
|
452
|
+
AND NOT COALESCE(cg.deleted, 0)
|
|
453
|
+
AND LOWER(cg.name) = LOWER(icg.name)
|
|
454
|
+
WHERE cg.id IS NULL
|
|
455
|
+
UNION ALL
|
|
456
|
+
SELECT
|
|
457
|
+
'Unknown exclude category group in plan '
|
|
458
|
+
|| sp.name
|
|
459
|
+
|| ': '
|
|
460
|
+
|| ecg.name AS error
|
|
461
|
+
FROM scoped_plans AS sp
|
|
462
|
+
CROSS JOIN exclude_category_groups AS ecg
|
|
463
|
+
LEFT JOIN category_groups AS cg
|
|
464
|
+
ON
|
|
465
|
+
sp.id = cg.plan_id
|
|
466
|
+
AND NOT COALESCE(cg.deleted, 0)
|
|
467
|
+
AND LOWER(cg.name) = LOWER(ecg.name)
|
|
468
|
+
WHERE cg.id IS NULL
|
|
381
469
|
)
|
|
382
470
|
|
|
383
471
|
, valid_params AS (
|
|
384
472
|
SELECT
|
|
385
473
|
v.account_name_like
|
|
474
|
+
, v.plan_id
|
|
386
475
|
, v.include_category_groups
|
|
387
476
|
, v.exclude_category_groups
|
|
388
477
|
FROM validation AS v
|
|
@@ -405,7 +494,7 @@ WITH params AS (
|
|
|
405
494
|
TRUE
|
|
406
495
|
AND NOT a.deleted
|
|
407
496
|
AND a.name LIKE v.account_name_like
|
|
408
|
-
AND (
|
|
497
|
+
AND (v.plan_id = '' OR p.id = v.plan_id)
|
|
409
498
|
)
|
|
410
499
|
|
|
411
500
|
, category_totals AS (
|
|
@@ -420,36 +509,61 @@ WITH params AS (
|
|
|
420
509
|
AND c.category_group_name != 'Internal Master Category'
|
|
421
510
|
AND (
|
|
422
511
|
v.include_category_groups = ''
|
|
423
|
-
OR
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
, ',' || LOWER(c.category_group_name) || ','
|
|
512
|
+
OR EXISTS (
|
|
513
|
+
SELECT 1
|
|
514
|
+
FROM include_category_groups AS icg
|
|
515
|
+
WHERE LOWER(icg.name) = LOWER(c.category_group_name)
|
|
428
516
|
)
|
|
429
|
-
> 0
|
|
430
517
|
)
|
|
431
518
|
AND (
|
|
432
519
|
v.exclude_category_groups = ''
|
|
433
|
-
OR
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
, ',' || LOWER(c.category_group_name) || ','
|
|
520
|
+
OR NOT EXISTS (
|
|
521
|
+
SELECT 1
|
|
522
|
+
FROM exclude_category_groups AS ecg
|
|
523
|
+
WHERE LOWER(ecg.name) = LOWER(c.category_group_name)
|
|
438
524
|
)
|
|
439
|
-
= 0
|
|
440
525
|
)
|
|
441
|
-
AND (
|
|
526
|
+
AND (v.plan_id = '' OR c.plan_id = v.plan_id)
|
|
442
527
|
GROUP BY c.plan_id
|
|
443
528
|
)
|
|
444
529
|
|
|
445
530
|
SELECT
|
|
446
|
-
|
|
531
|
+
ve.error AS error_message
|
|
532
|
+
, NULL AS "plan"
|
|
533
|
+
, NULL AS account
|
|
534
|
+
, NULL AS total
|
|
535
|
+
, NULL AS excess
|
|
536
|
+
FROM validation_errors AS ve
|
|
537
|
+
|
|
538
|
+
UNION ALL
|
|
539
|
+
|
|
540
|
+
SELECT
|
|
541
|
+
NULL AS error_message
|
|
542
|
+
, ma.plan_name AS "plan"
|
|
447
543
|
, ma.account_name AS account
|
|
448
544
|
, PRINTF('%.2f', COALESCE(ct.total, 0)) AS total
|
|
449
|
-
, PRINTF('%.2f', COALESCE(ct.total, 0)
|
|
545
|
+
, PRINTF('%.2f', ma.account_amount - COALESCE(ct.total, 0)) AS excess
|
|
450
546
|
FROM matched_accounts AS ma
|
|
451
547
|
LEFT JOIN category_totals AS ct ON ma.plan_id = ct.plan_id
|
|
452
|
-
|
|
548
|
+
;
|
|
549
|
+
|
|
550
|
+
SELECT error_message
|
|
551
|
+
FROM excess_query_results
|
|
552
|
+
WHERE error_message IS NOT NULL
|
|
553
|
+
;
|
|
554
|
+
|
|
555
|
+
SELECT
|
|
556
|
+
eqr."plan"
|
|
557
|
+
, eqr.account
|
|
558
|
+
, eqr.total
|
|
559
|
+
, eqr.excess
|
|
560
|
+
FROM excess_query_results AS eqr
|
|
561
|
+
WHERE
|
|
562
|
+
NOT EXISTS (
|
|
563
|
+
SELECT 1
|
|
564
|
+
FROM excess_query_results AS eqr_errors
|
|
565
|
+
WHERE eqr_errors.error_message IS NOT NULL
|
|
566
|
+
)
|
|
453
567
|
;
|
|
454
568
|
```
|
|
455
569
|
|