diff --git a/.gitignore b/.gitignore index fd0f5d7..3e05254 100644 --- a/.gitignore +++ b/.gitignore @@ -39,5 +39,51 @@ ENV/ ehthumbs.db Thumbs.db +# Environment variables +.env +.env.* +!.env.template + +# Python +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# Virtual Environment +venv/ +ENV/ + +# IDE +.idea/ +.vscode/ +*.swp +*.swo + +# OS +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db + # Environment variables .env \ No newline at end of file diff --git a/Connect_to_QuickBooks_buttons/.DS_Store b/Connect_to_QuickBooks_buttons/.DS_Store deleted file mode 100644 index ebc97f3..0000000 Binary files a/Connect_to_QuickBooks_buttons/.DS_Store and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/.DS_Store b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/.DS_Store deleted file mode 100644 index 8e4349b..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/.DS_Store and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_1x/.DS_Store b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_1x/.DS_Store deleted file mode 100644 index 5008ddf..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_1x/.DS_Store and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_1x/C2QB_green_btn_med_default.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_1x/C2QB_green_btn_med_default.png deleted file mode 100644 index b874b97..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_1x/C2QB_green_btn_med_default.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_1x/C2QB_green_btn_med_hover.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_1x/C2QB_green_btn_med_hover.png deleted file mode 100644 index 4e9988f..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_1x/C2QB_green_btn_med_hover.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_1x/C2QB_green_btn_short_default.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_1x/C2QB_green_btn_short_default.png deleted file mode 100644 index 5ef5e1e..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_1x/C2QB_green_btn_short_default.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_1x/C2QB_green_btn_short_hover.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_1x/C2QB_green_btn_short_hover.png deleted file mode 100644 index 4623695..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_1x/C2QB_green_btn_short_hover.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_1x/C2QB_green_btn_tall_hover.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_1x/C2QB_green_btn_tall_hover.png deleted file mode 100644 index 3ecf417..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_1x/C2QB_green_btn_tall_hover.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_1x/C2QB_transparent_btn_med_default.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_1x/C2QB_transparent_btn_med_default.png deleted file mode 100644 index 52e8e30..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_1x/C2QB_transparent_btn_med_default.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_1x/C2QB_transparent_btn_med_hover.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_1x/C2QB_transparent_btn_med_hover.png deleted file mode 100644 index c944435..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_1x/C2QB_transparent_btn_med_hover.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_1x/C2QB_transparent_btn_short_default.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_1x/C2QB_transparent_btn_short_default.png deleted file mode 100644 index 89016ad..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_1x/C2QB_transparent_btn_short_default.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_1x/C2QB_transparent_btn_short_hover.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_1x/C2QB_transparent_btn_short_hover.png deleted file mode 100644 index ef0db74..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_1x/C2QB_transparent_btn_short_hover.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_1x/C2QB_transparent_btn_tall_hover.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_1x/C2QB_transparent_btn_tall_hover.png deleted file mode 100644 index fb786af..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_1x/C2QB_transparent_btn_tall_hover.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_2x/C2QB_green_btn_med_default_2x.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_2x/C2QB_green_btn_med_default_2x.png deleted file mode 100644 index d373ade..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_2x/C2QB_green_btn_med_default_2x.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_2x/C2QB_green_btn_med_hover_2x.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_2x/C2QB_green_btn_med_hover_2x.png deleted file mode 100644 index ffb069b..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_2x/C2QB_green_btn_med_hover_2x.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_2x/C2QB_green_btn_short_default_2x.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_2x/C2QB_green_btn_short_default_2x.png deleted file mode 100644 index 51646aa..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_2x/C2QB_green_btn_short_default_2x.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_2x/C2QB_green_btn_short_hover_2x.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_2x/C2QB_green_btn_short_hover_2x.png deleted file mode 100644 index def4872..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_2x/C2QB_green_btn_short_hover_2x.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_2x/C2QB_green_btn_tall_default_2x.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_2x/C2QB_green_btn_tall_default_2x.png deleted file mode 100644 index 69ed2ac..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_2x/C2QB_green_btn_tall_default_2x.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_2x/C2QB_green_btn_tall_hover_2x.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_2x/C2QB_green_btn_tall_hover_2x.png deleted file mode 100644 index b747f16..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_2x/C2QB_green_btn_tall_hover_2x.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_2x/C2QB_transparent_btn_med_default_2x.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_2x/C2QB_transparent_btn_med_default_2x.png deleted file mode 100644 index 064634c..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_2x/C2QB_transparent_btn_med_default_2x.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_2x/C2QB_transparent_btn_med_hover_2x.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_2x/C2QB_transparent_btn_med_hover_2x.png deleted file mode 100644 index e1b457b..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_2x/C2QB_transparent_btn_med_hover_2x.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_2x/C2QB_transparent_btn_short_default2x.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_2x/C2QB_transparent_btn_short_default2x.png deleted file mode 100644 index 244ebe5..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_2x/C2QB_transparent_btn_short_default2x.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_2x/C2QB_transparent_btn_short_hover2x.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_2x/C2QB_transparent_btn_short_hover2x.png deleted file mode 100644 index 639b658..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_2x/C2QB_transparent_btn_short_hover2x.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_2x/C2QB_transparent_btn_tall_default2x.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_2x/C2QB_transparent_btn_tall_default2x.png deleted file mode 100644 index 2fd1991..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_2x/C2QB_transparent_btn_tall_default2x.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_2x/C2QB_transparent_btn_tall_hover2x.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_2x/C2QB_transparent_btn_tall_hover2x.png deleted file mode 100644 index 756940a..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_2x/C2QB_transparent_btn_tall_hover2x.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_SVG/C2QB_green_btn_med_default.svg b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_SVG/C2QB_green_btn_med_default.svg deleted file mode 100644 index 5777594..0000000 --- a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_SVG/C2QB_green_btn_med_default.svg +++ /dev/null @@ -1,4 +0,0 @@ - diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_SVG/C2QB_green_btn_med_hover.svg b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_SVG/C2QB_green_btn_med_hover.svg deleted file mode 100644 index 4495659..0000000 --- a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_SVG/C2QB_green_btn_med_hover.svg +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_SVG/C2QB_green_btn_short_default.svg b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_SVG/C2QB_green_btn_short_default.svg deleted file mode 100644 index f5e02d0..0000000 --- a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_SVG/C2QB_green_btn_short_default.svg +++ /dev/null @@ -1,4 +0,0 @@ - diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_SVG/C2QB_green_btn_short_hover.svg b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_SVG/C2QB_green_btn_short_hover.svg deleted file mode 100644 index 41c42a2..0000000 --- a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_SVG/C2QB_green_btn_short_hover.svg +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_SVG/C2QB_green_btn_tall_default.svg b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_SVG/C2QB_green_btn_tall_default.svg deleted file mode 100644 index d93a0e4..0000000 --- a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_SVG/C2QB_green_btn_tall_default.svg +++ /dev/null @@ -1,4 +0,0 @@ - diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_SVG/C2QB_green_btn_tall_hover.svg b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_SVG/C2QB_green_btn_tall_hover.svg deleted file mode 100644 index 78e4f76..0000000 --- a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_SVG/C2QB_green_btn_tall_hover.svg +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_SVG/C2QB_transparent_btn_med_default.svg b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_SVG/C2QB_transparent_btn_med_default.svg deleted file mode 100644 index 575057b..0000000 --- a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_SVG/C2QB_transparent_btn_med_default.svg +++ /dev/null @@ -1,4 +0,0 @@ - diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_SVG/C2QB_transparent_btn_med_hover.svg b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_SVG/C2QB_transparent_btn_med_hover.svg deleted file mode 100644 index f4bab4f..0000000 --- a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_SVG/C2QB_transparent_btn_med_hover.svg +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_SVG/C2QB_transparent_btn_short_default.svg b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_SVG/C2QB_transparent_btn_short_default.svg deleted file mode 100644 index d1c15ab..0000000 --- a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_SVG/C2QB_transparent_btn_short_default.svg +++ /dev/null @@ -1,4 +0,0 @@ - diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_SVG/C2QB_transparent_btn_short_hover.svg b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_SVG/C2QB_transparent_btn_short_hover.svg deleted file mode 100644 index ab88da6..0000000 --- a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_SVG/C2QB_transparent_btn_short_hover.svg +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_SVG/C2QB_transparent_btn_tall_default.svg b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_SVG/C2QB_transparent_btn_tall_default.svg deleted file mode 100644 index 66d56b3..0000000 --- a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_SVG/C2QB_transparent_btn_tall_default.svg +++ /dev/null @@ -1,4 +0,0 @@ - diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_SVG/C2QB_transparent_btn_tall_hover.svg b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_SVG/C2QB_transparent_btn_tall_hover.svg deleted file mode 100644 index d8319ae..0000000 --- a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_SVG/C2QB_transparent_btn_tall_hover.svg +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/.DS_Store b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/.DS_Store deleted file mode 100644 index 5c62855..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/.DS_Store and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_1x/C2QB_FR_green_btn_med_default.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_1x/C2QB_FR_green_btn_med_default.png deleted file mode 100644 index 254f920..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_1x/C2QB_FR_green_btn_med_default.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_1x/C2QB_FR_green_btn_med_hover.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_1x/C2QB_FR_green_btn_med_hover.png deleted file mode 100644 index f2fbd4d..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_1x/C2QB_FR_green_btn_med_hover.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_1x/C2QB_FR_green_btn_short_default.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_1x/C2QB_FR_green_btn_short_default.png deleted file mode 100644 index 825c582..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_1x/C2QB_FR_green_btn_short_default.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_1x/C2QB_FR_green_btn_short_hover.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_1x/C2QB_FR_green_btn_short_hover.png deleted file mode 100644 index 2da7b29..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_1x/C2QB_FR_green_btn_short_hover.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_1x/C2QB_FR_green_btn_tall_default.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_1x/C2QB_FR_green_btn_tall_default.png deleted file mode 100644 index 2226b83..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_1x/C2QB_FR_green_btn_tall_default.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_1x/C2QB_FR_green_btn_tall_hover.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_1x/C2QB_FR_green_btn_tall_hover.png deleted file mode 100644 index b21ae91..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_1x/C2QB_FR_green_btn_tall_hover.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_1x/C2QB_FR_transparent_btn_med_default.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_1x/C2QB_FR_transparent_btn_med_default.png deleted file mode 100644 index f18735f..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_1x/C2QB_FR_transparent_btn_med_default.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_1x/C2QB_FR_transparent_btn_med_hover.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_1x/C2QB_FR_transparent_btn_med_hover.png deleted file mode 100644 index b972f0b..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_1x/C2QB_FR_transparent_btn_med_hover.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_1x/C2QB_FR_transparent_btn_short_default.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_1x/C2QB_FR_transparent_btn_short_default.png deleted file mode 100644 index c7a13f9..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_1x/C2QB_FR_transparent_btn_short_default.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_1x/C2QB_FR_transparent_btn_short_hover.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_1x/C2QB_FR_transparent_btn_short_hover.png deleted file mode 100644 index 721d825..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_1x/C2QB_FR_transparent_btn_short_hover.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_1x/C2QB_FR_transparent_btn_tall_default.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_1x/C2QB_FR_transparent_btn_tall_default.png deleted file mode 100644 index 0c72b62..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_1x/C2QB_FR_transparent_btn_tall_default.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_1x/C2QB_FR_transparent_btn_tall_hover.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_1x/C2QB_FR_transparent_btn_tall_hover.png deleted file mode 100644 index 2c04ad5..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_1x/C2QB_FR_transparent_btn_tall_hover.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_2x/C2QB_FR_green_btn_med_default_2x.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_2x/C2QB_FR_green_btn_med_default_2x.png deleted file mode 100644 index 7763357..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_2x/C2QB_FR_green_btn_med_default_2x.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_2x/C2QB_FR_green_btn_med_hover_2x.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_2x/C2QB_FR_green_btn_med_hover_2x.png deleted file mode 100644 index f77024b..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_2x/C2QB_FR_green_btn_med_hover_2x.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_2x/C2QB_FR_green_btn_short_default_2x.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_2x/C2QB_FR_green_btn_short_default_2x.png deleted file mode 100644 index 6ae1774..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_2x/C2QB_FR_green_btn_short_default_2x.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_2x/C2QB_FR_green_btn_short_hover_2x.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_2x/C2QB_FR_green_btn_short_hover_2x.png deleted file mode 100644 index 29ab015..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_2x/C2QB_FR_green_btn_short_hover_2x.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_2x/C2QB_FR_green_btn_tall_default_2x.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_2x/C2QB_FR_green_btn_tall_default_2x.png deleted file mode 100644 index 9b114b0..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_2x/C2QB_FR_green_btn_tall_default_2x.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_2x/C2QB_FR_green_btn_tall_hover_2x.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_2x/C2QB_FR_green_btn_tall_hover_2x.png deleted file mode 100644 index c3d638c..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_2x/C2QB_FR_green_btn_tall_hover_2x.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_2x/C2QB_FR_transparent_btn_med_default_2x.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_2x/C2QB_FR_transparent_btn_med_default_2x.png deleted file mode 100644 index 06e1a86..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_2x/C2QB_FR_transparent_btn_med_default_2x.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_2x/C2QB_FR_transparent_btn_med_hover_2x.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_2x/C2QB_FR_transparent_btn_med_hover_2x.png deleted file mode 100644 index 87c129c..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_2x/C2QB_FR_transparent_btn_med_hover_2x.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_2x/C2QB_FR_transparent_btn_short_default_2x.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_2x/C2QB_FR_transparent_btn_short_default_2x.png deleted file mode 100644 index 6310812..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_2x/C2QB_FR_transparent_btn_short_default_2x.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_2x/C2QB_FR_transparent_btn_short_hover_2x.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_2x/C2QB_FR_transparent_btn_short_hover_2x.png deleted file mode 100644 index 9637eda..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_2x/C2QB_FR_transparent_btn_short_hover_2x.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_2x/C2QB_FR_transparent_btn_tall_default_2x.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_2x/C2QB_FR_transparent_btn_tall_default_2x.png deleted file mode 100644 index ca2d3f6..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_2x/C2QB_FR_transparent_btn_tall_default_2x.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_2x/C2QB_FR_transparent_btn_tall_hover_2x.png b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_2x/C2QB_FR_transparent_btn_tall_hover_2x.png deleted file mode 100644 index fda29ef..0000000 Binary files a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_2x/C2QB_FR_transparent_btn_tall_hover_2x.png and /dev/null differ diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_SVG/C2QB_FR_green_btn_med_default.svg b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_SVG/C2QB_FR_green_btn_med_default.svg deleted file mode 100644 index 9ab77f9..0000000 --- a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_SVG/C2QB_FR_green_btn_med_default.svg +++ /dev/null @@ -1,4 +0,0 @@ - diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_SVG/C2QB_FR_green_btn_med_hover.svg b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_SVG/C2QB_FR_green_btn_med_hover.svg deleted file mode 100644 index 26620ce..0000000 --- a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_SVG/C2QB_FR_green_btn_med_hover.svg +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_SVG/C2QB_FR_green_btn_short_default.svg b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_SVG/C2QB_FR_green_btn_short_default.svg deleted file mode 100644 index 04cede5..0000000 --- a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_SVG/C2QB_FR_green_btn_short_default.svg +++ /dev/null @@ -1,4 +0,0 @@ - diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_SVG/C2QB_FR_green_btn_short_hover.svg b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_SVG/C2QB_FR_green_btn_short_hover.svg deleted file mode 100644 index 99133e6..0000000 --- a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_SVG/C2QB_FR_green_btn_short_hover.svg +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_SVG/C2QB_FR_green_btn_tall_default.svg b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_SVG/C2QB_FR_green_btn_tall_default.svg deleted file mode 100644 index dfbe1c0..0000000 --- a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_SVG/C2QB_FR_green_btn_tall_default.svg +++ /dev/null @@ -1,4 +0,0 @@ - diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_SVG/C2QB_FR_green_btn_tall_hover.svg b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_SVG/C2QB_FR_green_btn_tall_hover.svg deleted file mode 100644 index 35573b0..0000000 --- a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_SVG/C2QB_FR_green_btn_tall_hover.svg +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_SVG/C2QB_FR_transparent_btn_med_default.svg b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_SVG/C2QB_FR_transparent_btn_med_default.svg deleted file mode 100644 index 555de64..0000000 --- a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_SVG/C2QB_FR_transparent_btn_med_default.svg +++ /dev/null @@ -1,4 +0,0 @@ - diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_SVG/C2QB_FR_transparent_btn_med_hover.svg b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_SVG/C2QB_FR_transparent_btn_med_hover.svg deleted file mode 100644 index 80b779e..0000000 --- a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_SVG/C2QB_FR_transparent_btn_med_hover.svg +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_SVG/C2QB_FR_transparent_btn_short_default.svg b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_SVG/C2QB_FR_transparent_btn_short_default.svg deleted file mode 100644 index 7fa593c..0000000 --- a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_SVG/C2QB_FR_transparent_btn_short_default.svg +++ /dev/null @@ -1,4 +0,0 @@ - diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_SVG/C2QB_FR_transparent_btn_short_hover.svg b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_SVG/C2QB_FR_transparent_btn_short_hover.svg deleted file mode 100644 index 5d7b0f8..0000000 --- a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_SVG/C2QB_FR_transparent_btn_short_hover.svg +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_SVG/C2QB_FR_transparent_btn_tall_default.svg b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_SVG/C2QB_FR_transparent_btn_tall_default.svg deleted file mode 100644 index 77a4c97..0000000 --- a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_SVG/C2QB_FR_transparent_btn_tall_default.svg +++ /dev/null @@ -1,4 +0,0 @@ - diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_SVG/C2QB_FR_transparent_btn_tall_hover.svg b/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_SVG/C2QB_FR_transparent_btn_tall_hover.svg deleted file mode 100644 index a508ffb..0000000 --- a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_Francais/Connect_to_QuickBooksFR_SVG/C2QB_FR_transparent_btn_tall_hover.svg +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/FlaskApp/.env.template b/FlaskApp/.env.template new file mode 100644 index 0000000..82f8a4f --- /dev/null +++ b/FlaskApp/.env.template @@ -0,0 +1,8 @@ +# QuickBooks OAuth2 Configuration +QB_CLIENT_ID="client Id" +QB_CLIENT_SECRET="client secret" +QB_REDIRECT_URI= "redirect url" +QB_ENVIRONMENT=production # or 'sandbox' for testing + +# Note: Replace the values above with your actual QuickBooks Developer credentials +# Do not commit your actual .env file to version control diff --git a/FlaskApp/__init__.py b/FlaskApp/__init__.py new file mode 100644 index 0000000..3f359a3 --- /dev/null +++ b/FlaskApp/__init__.py @@ -0,0 +1,11 @@ +from flask import Flask +from .config import Config + +def create_app(): + app = Flask(__name__) + app.config.from_object(Config) + + from .app import main as main_blueprint + app.register_blueprint(main_blueprint) + + return app \ No newline at end of file diff --git a/app.py b/FlaskApp/app.py similarity index 58% rename from app.py rename to FlaskApp/app.py index 2d8e7d5..c018e2d 100644 --- a/app.py +++ b/FlaskApp/app.py @@ -13,7 +13,14 @@ static_folder='static', static_url_path='/static', template_folder='templates') -app.secret_key = 'your-secret-key-123' # Replace with your own secret key + +# Configure session +app.secret_key = os.urandom(24) +app.config['SESSION_TYPE'] = 'filesystem' +app.config['PERMANENT_SESSION_LIFETIME'] = 3600 # 1 hour +app.config['SESSION_COOKIE_SECURE'] = False # Set to False for development +app.config['SESSION_COOKIE_HTTPONLY'] = True +app.config['SESSION_COOKIE_SAMESITE'] = 'Lax' # Clear session on startup @app.before_request @@ -77,38 +84,29 @@ def fetch_custom_fields(token, realm_id): custom_fields = [] if token and realm_id: headers = get_headers(token['access_token']) - query = ''' - query { - appFoundationsCustomFieldDefinitions { - edges { - node { - id - legacyIDV2 - label - active - associations { - associatedEntity - active - validationOptions { required } - allowedOperations - associationCondition - subAssociations { - associatedEntity - active - allowedOperations - } - } - } - } - } - } - ''' + + # Read GraphQL query from file + try: + with open(os.path.join(app.static_folder, 'graphql', 'query_custom_field.graphql'), 'r') as file: + query = file.read() + except Exception as e: + error_msg = f"Failed to read GraphQL query file: {str(e)}" + print(error_msg) + flash(error_msg, "danger") + return custom_fields + payload = {"query": query} try: + print("Sending GraphQL request for custom fields...") resp = requests.post(QB_GRAPHQL_URL, json=payload, headers=headers) + print(f"Custom fields response status: {resp.status_code}") + print(f"Custom fields response: {resp.text}") + resp_json = resp.json() if resp.status_code == 200 and resp_json.get('data'): edges = resp_json['data']['appFoundationsCustomFieldDefinitions']['edges'] + print(f"Found {len(edges)} custom field edges") + for edge in edges: node = edge['node'] if node.get('active', False): @@ -118,180 +116,203 @@ def fetch_custom_fields(token, realm_id): for sub_assoc in assoc.get('subAssociations', []): transaction_types.append(sub_assoc.get('associatedEntity', '')) - custom_fields.append({ + custom_field = { 'id': node['id'], 'legacyIDV2': node['legacyIDV2'], 'label': node['label'], 'active': node['active'], 'transaction_types': transaction_types, 'selected': True - }) + } + custom_fields.append(custom_field) + print(f"Added custom field: {custom_field}") + else: + print(f"Error in custom fields response: {resp_json.get('errors', [])}") except Exception as e: + print(f"Exception fetching custom fields: {str(e)}") flash(f"Error fetching custom fields: {str(e)}", "danger") return custom_fields @app.route("/login") def login(): - scopes = [ "com.intuit.quickbooks.accounting", "app-foundations.custom-field-definitions" ] params = { + "response_type": "code", "client_id": QB_CLIENT_ID, "redirect_uri": QB_REDIRECT_URI, - "response_type": "code", "scope": " ".join(scopes), - "state": "random_state_123" + "state": "random_state_123", # Send state but don't validate + "locale": "en-us" } - auth_url = f"{QB_AUTH_URL}?{urllib.parse.urlencode(params)}" + encoded_params = urllib.parse.urlencode(params, quote_via=urllib.parse.quote) + auth_url = f"{QB_AUTH_URL}?{encoded_params}" return redirect(auth_url) @app.route("/callback") def callback(): session.pop('_flashes', None) + # Log all callback parameters for debugging + print(f"Callback parameters: {dict(request.args)}") + + # Check for OAuth errors + error = request.args.get('error') + error_description = request.args.get('error_description') + if error: + error_msg = f"OAuth Error: {error} - {error_description}" + print(f"OAuth Error in callback: {error_msg}") + flash(error_msg, "danger") + return render_template('index.html', token=None, custom_fields=[]) + auth_code = request.args.get('code') realm_id = request.args.get('realmId') + if not auth_code or not realm_id: - flash("Missing code or realmId in callback.", "danger") - return redirect(url_for('index')) + error_msg = "Missing code or realmId in callback" + print(f"Missing parameters: {error_msg}") + flash(error_msg, "danger") + return render_template('index.html', token=None, custom_fields=[]) - headers = {"Accept": "application/json"} + headers = { + "Accept": "application/json", + "Content-Type": "application/x-www-form-urlencoded" + } auth = (QB_CLIENT_ID, QB_CLIENT_SECRET) data = { "grant_type": "authorization_code", "code": auth_code, "redirect_uri": QB_REDIRECT_URI } - resp = requests.post(QB_OAUTH_URL, headers=headers, data=data, auth=auth) - if resp.status_code == 200: - token_json = resp.json() - session['oauth_token'] = { - 'access_token': token_json.get('access_token'), - 'refresh_token': token_json.get('refresh_token'), - 'id_token': token_json.get('id_token'), - 'expires_in': token_json.get('expires_in'), - } - session['realm_id'] = realm_id - - # Initialize all session data after successful authentication - customers = fetch_customers(session['oauth_token'], realm_id) - items = fetch_items(session['oauth_token'], realm_id) - custom_fields = fetch_custom_fields(session['oauth_token'], realm_id) - - session['customers'] = customers - session['items'] = items - session['custom_fields'] = custom_fields + + try: + print(f"Token request data: {data}") + resp = requests.post(QB_OAUTH_URL, headers=headers, data=data, auth=auth) + print(f"Token response status: {resp.status_code}") + print(f"Token response: {resp.text}") - flash("Successfully authenticated with QuickBooks!", "success") - else: - flash(f"Failed to get tokens: {resp.text}", "danger") - return redirect(url_for('index')) + if resp.status_code == 200: + token_json = resp.json() + # Store token data in session + session['oauth_token'] = { + 'access_token': token_json.get('access_token'), + 'refresh_token': token_json.get('refresh_token'), + 'id_token': token_json.get('id_token'), + 'expires_in': token_json.get('expires_in'), + } + session['realm_id'] = realm_id + + # Initialize all session data after successful authentication + print("Fetching customers...") + customers = fetch_customers(session['oauth_token'], realm_id) + session['customers'] = customers + print(f"Fetched {len(customers)} customers") + + print("Fetching items...") + items = fetch_items(session['oauth_token'], realm_id) + session['items'] = items + print(f"Fetched {len(items)} items") + + print("Fetching custom fields...") + custom_fields = fetch_custom_fields(session['oauth_token'], realm_id) + session['custom_fields'] = custom_fields + print(f"Fetched {len(custom_fields)} custom fields") + print("Custom fields:", custom_fields) + + flash("Successfully authenticated with QuickBooks!", "success") + return render_template('index.html', + token=session['oauth_token'], + custom_fields=custom_fields, + customers=customers, + items=items) + else: + error_msg = f"Failed to get tokens. Status: {resp.status_code}, Response: {resp.text}" + print(f"Token request failed: {error_msg}") + flash(error_msg, "danger") + return render_template('index.html', token=None, custom_fields=[]) + except Exception as e: + error_msg = f"Exception during OAuth token exchange: {str(e)}" + print(f"Exception in callback: {error_msg}") + flash(error_msg, "danger") + return render_template('index.html', token=None, custom_fields=[]) -@app.route("/create_tag", methods=["POST"]) -def create_tag(): +@app.route("/create_custom_field", methods=["POST"]) +def create_custom_field(): session.pop('_flashes', None) + session.pop('error_code', None) # Clear any previous error code - tag_name = request.form.get("tag_name") + custom_field_name = request.form.get("custom_field_name") token = session.get("oauth_token") realm_id = session.get("realm_id") - if not token or not realm_id: - flash("Please connect to QuickBooks first.", "danger") + + # Read GraphQL mutation from file + try: + with open(os.path.join(app.static_folder, 'graphql', 'custom_field.graphql'), 'r') as file: + mutation = file.read() + except Exception as e: + error_msg = f"Failed to read GraphQL mutation file: {str(e)}" + print(error_msg) + flash(error_msg, "danger") + return redirect(url_for('index')) + + # Read variables template from file + try: + with open(os.path.join(app.static_folder, 'graphql', 'custom_field_variables.json'), 'r') as file: + variables_template = json.load(file) + # Replace the placeholder with actual value + variables_template['input']['label'] = custom_field_name + except Exception as e: + error_msg = f"Failed to read variables template file: {str(e)}" + print(error_msg) + flash(error_msg, "danger") return redirect(url_for('index')) - headers = get_headers(token['access_token']) - mutation = ''' - mutation AppFoundationsCreateCustomFieldDefinition($input: AppFoundations_CustomFieldDefinitionCreateInput!) { - appFoundationsCreateCustomFieldDefinition(input: $input) { - label - active - associations { - associatedEntity - active - validationOptions { required } - allowedOperations - associationCondition - subAssociations { - associatedEntity - active - allowedOperations - } - } - dataType - dropDownOptions { - value - active - order - } - } - } - ''' - variables = { - "input": { - "label": tag_name, - "associations": [ - { - "validationOptions": {"required": False}, - "associatedEntity": "/transactions/Transaction", - "active": True, - "allowedOperations": [], - "associationCondition": "INCLUDED", - "subAssociations": [ - { - "associatedEntity": "SALE_INVOICE", - "active": True, - "allowedOperations": [] - } - ] - }, - { - "associatedEntity": "/network/Contact", - "active": True, - "validationOptions": {"required": False}, - "allowedOperations": [], - "associationCondition": "INCLUDED", - "subAssociations": [ - { - "associatedEntity": "CUSTOMER", - "active": True, - "allowedOperations": [] - } - ] - } - ], - "dataType": "STRING", - "active": True - } - } payload = { "query": mutation, - "variables": variables + "variables": variables_template } try: - resp = requests.post(QB_GRAPHQL_URL, json=payload, headers=headers) + print(f"Creating new custom field with name: {custom_field_name}") + resp = requests.post(QB_GRAPHQL_URL, json=payload, headers=get_headers(token['access_token'])) resp_json = resp.json() - except Exception as e: - flash(f"Failed to create tag: {e}", "danger") - return redirect(url_for('index')) - - if resp_json.get('errors'): - for error in resp_json['errors']: - if error.get('extensions', {}).get('errorCode', {}).get('errorCode') == "CUSTOM_FIELD_ASSOCIATED_ENTITY_LIMIT_EXCEEDED": - flash("You've exceeded the maximum number of associated entities for custom fields.", "danger") + + if resp_json.get('errors'): + for error in resp_json['errors']: + error_code = error.get('extensions', {}).get('errorCode', {}).get('errorCode') + + # Store the error code in session + session['error_code'] = error_code + + # Handle specific error codes + if error_code == 'CUSTOM_FIELD_ASSOCIATED_ENTITY_LIMIT_EXCEEDED': + flash("You've exceeded the maximum number of associated entities for custom fields.", "danger") + elif error_code == 'LABEL_ALREADY_EXISTS': + flash("Custom field already exists", "danger") + else: + flash("Unknown error", "danger") return redirect(url_for('index')) - flash(f"Failed to create tag: {resp_json['errors']}", "danger") + + # After successful custom field creation, refresh custom fields + custom_fields = fetch_custom_fields(token, realm_id) + session['custom_fields'] = custom_fields + session['custom_field_name'] = custom_field_name # Store the created custom field name + + flash("Custom field created successfully.", "success") + return redirect(url_for('index')) + except Exception as e: + error_msg = f"Failed to create custom field: {str(e)}" + print(error_msg) + flash(error_msg, "danger") return redirect(url_for('index')) - - # After successful tag creation, only refresh custom fields - custom_fields = fetch_custom_fields(token, realm_id) - session['custom_fields'] = custom_fields - - flash("Tag created successfully.", "success") - return redirect(url_for('index')) @app.route("/create_invoice", methods=["POST"]) def create_invoice(): + + session.pop('invoice_id', None) + session.pop('invoice_deep_link', None) + amount = request.form.get("amount") token = session.get("oauth_token") realm_id = session.get("realm_id") @@ -300,6 +321,7 @@ def create_invoice(): customer_id = request.form.get("customer_id") item_id = request.form.get("item_id") item_name = request.form.get("item_name") + if not token or not realm_id or not custom_field_id or not customer_id or not item_id: flash("Connect to QuickBooks and select all required fields.", "danger") return redirect(url_for('index')) @@ -307,7 +329,7 @@ def create_invoice(): headers = get_headers(token['access_token']) headers["Accept-Encoding"] = "gzip, deflate" - url = f"{QB_BASE_URL}/{realm_id}/invoice?minorversion=70&include=enhancedAllCustomFields" + url = f"{QB_BASE_URL}/{realm_id}/invoice?minorversion=75&include=enhancedAllCustomFields" data = { "Line": [ { @@ -329,7 +351,12 @@ def create_invoice(): } try: + print(f"Sending invoice creation request to: {url}") + print(f"Request data: {json.dumps(data, indent=2)}") + resp = requests.post(url, json=data, headers=headers) + print(f"Invoice creation response status: {resp.status_code}") + print(f"Invoice creation response: {resp.text}") if resp.status_code == 200: resp_json = resp.json() @@ -337,22 +364,28 @@ def create_invoice(): inv_id = resp_json['Invoice']['Id'] session['invoice_id'] = inv_id - if inv_id: - deep_link = f"https://app.qbo.intuit.com/app/invoice?txnId={inv_id}&companyId={realm_id}" - session['invoice_deep_link'] = deep_link - flash(f"Success! Invoice created with ID: {inv_id}", "success") - else: - flash("Invoice created but ID not found in response", "warning") + # Create deep link + deep_link = f"https://app.qbo.intuit.com/app/invoice?txnId={inv_id}&companyId={realm_id}" + session['invoice_deep_link'] = deep_link + + flash(f"Success! Invoice created with ID: {inv_id}", "success") else: - flash("Invoice created but response format unexpected", "warning") + error_msg = "Invoice created but ID not found in response" + print(error_msg) + print(f"Response JSON: {json.dumps(resp_json, indent=2)}") + flash(error_msg, "warning") else: - session['invoice_id'] = None - session['invoice_deep_link'] = None - flash(f"Failed to create invoice: {resp.text}", "danger") + error_msg = f"Failed to create invoice. Status: {resp.status_code}, Response: {resp.text}" + print(error_msg) + flash(error_msg, "danger") except requests.exceptions.ContentDecodingError as e: - flash("Error creating invoice: Content decoding error", "danger") + error_msg = f"Error creating invoice: Content decoding error - {str(e)}" + print(error_msg) + flash(error_msg, "danger") except Exception as e: - flash(f"Error creating invoice: {str(e)}", "danger") + error_msg = f"Error creating invoice: {str(e)}" + print(error_msg) + flash(error_msg, "danger") return redirect(url_for('index')) @@ -479,5 +512,4 @@ def make_request(self, method, endpoint, data=None): pass if __name__ == "__main__": - app.run(host="0.0.0.0", port=5001, debug=True) - + app.run(host="0.0.0.0", port=5002, debug=True) \ No newline at end of file diff --git a/config.py b/FlaskApp/config.py similarity index 70% rename from config.py rename to FlaskApp/config.py index 5c3e94a..739467f 100644 --- a/config.py +++ b/FlaskApp/config.py @@ -5,26 +5,25 @@ from urllib.parse import urlencode from intuitlib.enums import Scopes - - # QuickBooks OAuth2 Configuration -QB_CLIENT_ID = "ABNqSMYyurXwhGpB21K9pcbFvxtlbZ356QKmn2LYjqsXeiIO2v" -QB_CLIENT_SECRET = "QgXeKbzMgHg4wVLqGgpHdFXqpQUGPvDyJ0Pw3O14" -QB_REDIRECT_URI = "https://b62d-2600-1700-5ae0-6400-7d4d-f798-2b01-b70c.ngrok-free.app/callback" -QB_ENVIRONMENT = "production" +# QuickBooks OAuth2 Configuration +QB_CLIENT_ID = os.getenv('QB_CLIENT_ID', '') +QB_CLIENT_SECRET = os.getenv('QB_CLIENT_SECRET', '') +QB_REDIRECT_URI = os.getenv('QB_REDIRECT_URI', '') +QB_ENVIRONMENT = os.getenv('QB_ENVIRONMENT', 'production') - # API Endpoints +# API Endpoints QB_BASE_URL = f"https://{'sandbox-quickbooks.api.intuit.com' if QB_ENVIRONMENT == 'sandbox' else 'quickbooks.api.intuit.com'}/v3/company" QB_OAUTH_URL = "https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer" QB_GRAPHQL_URL = "https://qb.api.intuit.com/graphql" QB_AUTH_URL = f"https://appcenter.intuit.com/connect/oauth2" - # OAuth2 Scopes +# OAuth2 Scopes QB_SCOPES = [ - "com.intuit.quickbooks.accounting", - "app-foundations.custom-field-definitions" - ] + Scopes.ACCOUNTING, + Scopes.CUSTOM_FIELDS +] - # API Headers +# API Headers def get_headers(token): """Generate standard headers for QuickBooks API requests""" return { @@ -33,7 +32,7 @@ def get_headers(token): "Content-Type": "application/json" } - # OAuth2 URL Generation +# OAuth2 URL Generation def get_auth_url(): """Generate the OAuth2 authorization URL""" params = { @@ -45,15 +44,15 @@ def get_auth_url(): } return f"{QB_AUTH_URL}?{urlencode(params)}" - # API Query Parameters +# API Query Parameters def get_query_params(query): """Generate URL-encoded query parameters""" return urlencode({"query": query}) - # Invoice Parameters -INVOICE_PARAMS = "?minorversion=70&include=enhancedAllCustomFields" +# Invoice Parameters +INVOICE_PARAMS = "?minorversion=75&include=enhancedAllCustomFields" - # Deep Link Base URL +# Deep Link Base URL QB_DEEP_LINK_BASE = "https://app.qbo.intuit.com/app/invoice" def get_deep_link(invoice_id, realm_id): diff --git a/requirements.txt b/FlaskApp/requirements.txt similarity index 100% rename from requirements.txt rename to FlaskApp/requirements.txt diff --git a/Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_1x/C2QB_green_btn_tall_default.png b/FlaskApp/static/C2QB_green_btn_tall_default.png similarity index 100% rename from Connect_to_QuickBooks_buttons/Connect_to_QuickBooks_English/Connect_to_QuickBooks_1x/C2QB_green_btn_tall_default.png rename to FlaskApp/static/C2QB_green_btn_tall_default.png diff --git a/static/C2QB_transparent_btn_tall_default.png b/FlaskApp/static/C2QB_transparent_btn_tall_default.png similarity index 100% rename from static/C2QB_transparent_btn_tall_default.png rename to FlaskApp/static/C2QB_transparent_btn_tall_default.png diff --git a/static/ConnectToQuickBooks.svg b/FlaskApp/static/ConnectToQuickBooks.svg similarity index 100% rename from static/ConnectToQuickBooks.svg rename to FlaskApp/static/ConnectToQuickBooks.svg diff --git a/FlaskApp/static/graphql/custom_field.graphql b/FlaskApp/static/graphql/custom_field.graphql new file mode 100644 index 0000000..ec69138 --- /dev/null +++ b/FlaskApp/static/graphql/custom_field.graphql @@ -0,0 +1,24 @@ +mutation AppFoundationsCreateCustomFieldDefinition($input: AppFoundations_CustomFieldDefinitionCreateInput!) { + appFoundationsCreateCustomFieldDefinition(input: $input) { + label + active + associations { + associatedEntity + active + validationOptions { required } + allowedOperations + associationCondition + subAssociations { + associatedEntity + active + allowedOperations + } + } + dataType + dropDownOptions { + value + active + order + } + } +} \ No newline at end of file diff --git a/FlaskApp/static/graphql/custom_field_variables.json b/FlaskApp/static/graphql/custom_field_variables.json new file mode 100644 index 0000000..0d46f30 --- /dev/null +++ b/FlaskApp/static/graphql/custom_field_variables.json @@ -0,0 +1,37 @@ +{ + "input": { + "label": "${label}", + "associations": [ + { + "validationOptions": {"required": false}, + "associatedEntity": "/transactions/Transaction", + "active": true, + "allowedOperations": [], + "associationCondition": "INCLUDED", + "subAssociations": [ + { + "associatedEntity": "SALE_INVOICE", + "active": true, + "allowedOperations": [] + } + ] + }, + { + "associatedEntity": "/network/Contact", + "active": true, + "validationOptions": {"required": false}, + "allowedOperations": [], + "associationCondition": "INCLUDED", + "subAssociations": [ + { + "associatedEntity": "CUSTOMER", + "active": true, + "allowedOperations": [] + } + ] + } + ], + "dataType": "STRING", + "active": true + } +} \ No newline at end of file diff --git a/FlaskApp/static/graphql/query_custom_field.graphql b/FlaskApp/static/graphql/query_custom_field.graphql new file mode 100644 index 0000000..edf309d --- /dev/null +++ b/FlaskApp/static/graphql/query_custom_field.graphql @@ -0,0 +1,24 @@ +query { + appFoundationsCustomFieldDefinitions { + edges { + node { + id + legacyIDV2 + label + active + associations { + associatedEntity + active + validationOptions { required } + allowedOperations + associationCondition + subAssociations { + associatedEntity + active + allowedOperations + } + } + } + } + } +} \ No newline at end of file diff --git a/static/images/logo_1x.png b/FlaskApp/static/images/logo_1x.png similarity index 100% rename from static/images/logo_1x.png rename to FlaskApp/static/images/logo_1x.png diff --git a/static/styles.css b/FlaskApp/static/styles.css similarity index 100% rename from static/styles.css rename to FlaskApp/static/styles.css diff --git a/templates/index.html b/FlaskApp/templates/index.html similarity index 60% rename from templates/index.html rename to FlaskApp/templates/index.html index bf28356..dd03ade 100644 --- a/templates/index.html +++ b/FlaskApp/templates/index.html @@ -29,6 +29,61 @@ color: #6c757d; margin-top: 5px; } + + .alert { + padding: 15px; + margin-bottom: 20px; + border: 1px solid transparent; + border-radius: 4px; + position: relative; + z-index: 1000; + } + .alert-danger { + color: #721c24; + background-color: #f8d7da; + border-color: #f5c6cb; + } + .alert-success { + color: #155724; + background-color: #d4edda; + border-color: #c3e6cb; + } + pre { + white-space: pre-wrap; + word-wrap: break-word; + margin: 0; + } + .status-error { + color: #721c24; + background-color: #f8d7da; + border: 1px solid #f5c6cb; + padding: 10px; + margin: 10px 0; + border-radius: 4px; + display: inline-block; + } + .invoice-status { + padding: 15px; + background-color: #f8f9fa; + border-radius: 4px; + margin-top: 10px; + } + + .btn-link { + display: inline-block; + padding: 5px 10px; + margin-left: 10px; + color: #007bff; + text-decoration: none; + border: 1px solid #007bff; + border-radius: 4px; + } + + .btn-link:hover { + background-color: #007bff; + color: white; + text-decoration: none; + }
@@ -36,13 +91,13 @@No active custom fields found.
+ {% if session.error_code %} +