setup
This commit is contained in:
		
						commit
						a90c1942e1
					
				
							
								
								
									
										5
									
								
								.env.example
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								.env.example
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| user= | ||||
| password= | ||||
| host= | ||||
| port= | ||||
| database= | ||||
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| node_modules/* | ||||
| .env | ||||
| *.log | ||||
							
								
								
									
										26
									
								
								.vscode/launch.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								.vscode/launch.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | ||||
| { | ||||
| 	"version": "0.1.0", | ||||
| 	"configurations": [ | ||||
|         { | ||||
|             "name": "Node Start", | ||||
|             "type": "node", | ||||
|             "program": "${workspaceRoot}/index.js", | ||||
|             "request": "launch", | ||||
|             "cwd": "${workspaceRoot}", | ||||
|             "runtimeExecutable": null, | ||||
|             "env": { | ||||
|                 "NODE_ENV": "developement" | ||||
|             } | ||||
|         }, | ||||
|         { | ||||
|             "name": "Mocha Test", | ||||
|             "type": "node", | ||||
|             "program": "${workspaceRoot}/node_modules/mocha/bin/_mocha", | ||||
|             "request": "launch", | ||||
|             "cwd": "${workspaceRoot}", | ||||
|             "runtimeExecutable": null, | ||||
|             "env": { | ||||
|                 "NODE_ENV": "testing" | ||||
|             } | ||||
|         }] | ||||
| } | ||||
							
								
								
									
										2
									
								
								index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								index.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,2 @@ | ||||
| var server = require('./server'); | ||||
| server.listen(80); | ||||
							
								
								
									
										27
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | ||||
| { | ||||
|   "name": "base", | ||||
|   "version": "1.0.0", | ||||
|   "description": "", | ||||
|   "main": "index.js", | ||||
|   "scripts": { | ||||
|     "test": "node_modules/mocha/bin/mocha", | ||||
|     "start": "node index.js" | ||||
|   }, | ||||
|   "author": "", | ||||
|   "license": "ISC", | ||||
|   "devDependencies": { | ||||
|     "chai": "^3.5.0", | ||||
|     "chai-http": "^3.0.0", | ||||
|     "mocha": "^2.5.3" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "body-parser": "^1.17.1", | ||||
|     "cookie-parser": "^1.4.3", | ||||
|     "csvtojson": "^2.0.0", | ||||
|     "dotenv": "^2.0.0", | ||||
|     "express": "^4.13.4", | ||||
|     "express-handlebars": "^3.0.0", | ||||
|     "multer": "^1.3.0", | ||||
|     "pg": "^7.4.1" | ||||
|   } | ||||
| } | ||||
							
								
								
									
										20
									
								
								readme.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								readme.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | ||||
| ### Interaction Details | ||||
| * Source Definitions (Maint/Inquire) | ||||
| 
 | ||||
|     * list `/srce_list` | ||||
|     * set `/srce_set` | ||||
| 
 | ||||
| * Regex Instructions (Maint/Inquire) | ||||
| 
 | ||||
|     * list `/regex_list` | ||||
|     * set `/regex_set` | ||||
| 
 | ||||
| * Cross Reference List (Maint/Inquire) | ||||
| 
 | ||||
|     * list `/map_list`  | ||||
|     * set `/map_set` | ||||
|     * show unampped `/unmapped` | ||||
| 
 | ||||
| * Run Import | ||||
| 
 | ||||
|     * run `/import_csv` takes a csv body | ||||
							
								
								
									
										258
									
								
								server.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										258
									
								
								server.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,258 @@ | ||||
| require('dotenv').config(); | ||||
| var express = require('express'); | ||||
| var handlebars = require('express-handlebars'); | ||||
| var bodyParser = require('body-parser'); | ||||
| var cookieParser = require('cookie-parser'); | ||||
| var mult = require('multer'); | ||||
| var upload = mult({ encoding: "utf8" }); | ||||
| var csvtojson = require('csvtojson'); | ||||
| var pg = require('pg'); | ||||
| 
 | ||||
| var server = express(); | ||||
| server.engine('handlebars', handlebars()); | ||||
| server.set('view engine', 'handlebars'); | ||||
| 
 | ||||
| 
 | ||||
| var Postgres = new pg.Client({ | ||||
|      | ||||
|     user: process.env.user, | ||||
|     password: process.env.password, | ||||
|     host: process.env.host, | ||||
|     port: process.env.port, | ||||
|     database: process.env.database, | ||||
|     application_name: "tps_etl_api", | ||||
|     ssl: true | ||||
| }) | ||||
| 
 | ||||
| Postgres.connect(); | ||||
| 
 | ||||
| //-------------------------------------------------------------list source--------------------------------------------------------------------------
 | ||||
| 
 | ||||
| server.use("/srce_list", function (inReq, inRes) { | ||||
| 
 | ||||
|     var sql = "SELECT jsonb_agg(defn) source_list FROM tps.srce" | ||||
|     console.log(sql); | ||||
| 
 | ||||
|     Postgres.query(sql, (err, res) => { | ||||
|         inRes.json(res.rows[0]); | ||||
|         console.log("source list request complete"); | ||||
|     }); | ||||
| } | ||||
| ); | ||||
| 
 | ||||
| //-------------------------------------------------------------list maps--------------------------------------------------------------------------
 | ||||
| 
 | ||||
| server.use("/map_list", function (inReq, inRes) { | ||||
| 
 | ||||
|     var sql = "SELECT jsonb_agg(regex) regex FROM tps.map_rm" | ||||
|     console.log(sql); | ||||
| 
 | ||||
|     Postgres.query(sql, (err, res) => { | ||||
| 
 | ||||
|         if (err === null) { | ||||
|             inRes.json(res.rows[0]); | ||||
|             return; | ||||
|         } | ||||
|         inRes.json(err.message); | ||||
|     }); | ||||
| } | ||||
| ); | ||||
| 
 | ||||
| //--------------------------------------------------------list unmapped items flagged to be mapped---------------------------------------------------
 | ||||
| 
 | ||||
| server.use("/unmapped", function (inReq, inRes) { | ||||
| 
 | ||||
|     var sql = "SELECT jsonb_agg(row_to_json(x)::jsonb) regex FROM tps.report_unmapped_recs('"; | ||||
|     sql += inReq.query.srce + "') x" | ||||
|     console.log(sql); | ||||
| 
 | ||||
|     Postgres.query(sql, (err, res) => { | ||||
| 
 | ||||
|         if (err === null) { | ||||
|             inRes.json(res.rows[0]); | ||||
|             return; | ||||
|         } | ||||
|         inRes.json(err.message); | ||||
|     }); | ||||
| } | ||||
| ); | ||||
| 
 | ||||
| //-------------------------------------------------------------set source via json in body--------------------------------------------------------------------------
 | ||||
| 
 | ||||
| server.use("/srce_set", bodyParser.json(), function (inReq, inRes) { | ||||
|      | ||||
|     //validate the body contents before pushing to sql?
 | ||||
|     var sql = "SELECT x.message FROM tps.srce_set($$"; | ||||
|     sql += JSON.stringify( inReq.body); | ||||
|     sql += "$$::jsonb) as x(message)"; | ||||
|     console.log(sql); | ||||
| 
 | ||||
|     Postgres.query(sql, (err, res) => { | ||||
| 
 | ||||
|         //Postgres.end();
 | ||||
| 
 | ||||
|         if (err === null) { | ||||
|             inRes.json(res.rows[0]); | ||||
|             return; | ||||
|         } | ||||
|         inRes.json(err.message); | ||||
|         //handle error
 | ||||
|     }); | ||||
| } | ||||
| ); | ||||
| 
 | ||||
| //-------------------------------------------------------------set one or more map definitions--------------------------------------------------------------------------
 | ||||
| 
 | ||||
| server.use("/mapdef_set", bodyParser.json(), function (inReq, inRes) { | ||||
| 
 | ||||
|     //validate the body contents before pushing to sql?
 | ||||
|     var sql = "SELECT x.message FROM tps.srce_map_def_set($$"; | ||||
|     sql += JSON.stringify( inReq.body); | ||||
|     sql += "$$::jsonb) as x(message)"; | ||||
|     console.log(sql); | ||||
| 
 | ||||
|     Postgres.query(sql, (err, res) => { | ||||
| 
 | ||||
|         //Postgres.end();
 | ||||
| 
 | ||||
|         if (err === null) { | ||||
|             inRes.json(res.rows[0]); | ||||
|             return; | ||||
|         } | ||||
|         inRes.json(err.message); | ||||
|         //handle error
 | ||||
|     }); | ||||
| 
 | ||||
| } | ||||
| ); | ||||
| 
 | ||||
| //-------------------------------------------------------------add entries to lookup table--------------------------------------------------------------------------
 | ||||
| 
 | ||||
| server.use("/mapval_set", bodyParser.json(), function (inReq, inRes) { | ||||
| 
 | ||||
|     //validate the body contents before pushing to sql?
 | ||||
|     var sql = "SELECT x.message FROM tps.map_rv_set($$"; | ||||
|     sql += JSON.stringify( inReq.body); | ||||
|     sql += "$$::jsonb) as x(message)"; | ||||
|     console.log(sql); | ||||
| 
 | ||||
|     Postgres.query(sql, (err, res) => { | ||||
| 
 | ||||
|         //Postgres.end();
 | ||||
| 
 | ||||
|         if (err === null) { | ||||
|             inRes.json(res.rows[0]); | ||||
|             return; | ||||
|         } | ||||
|         inRes.json(err.message); | ||||
|         //handle error
 | ||||
|     }); | ||||
| 
 | ||||
| } | ||||
| ); | ||||
| 
 | ||||
| /* | ||||
| send a csv with powershell: | ||||
| wget -uri http://localhost/import  -Method Post -InFile "C:\Users\fleet\Downloads\d.csv"
 | ||||
| bash | ||||
| curl -v -F upload=@//mnt/c/Users/fleet/Downloads/d.csv localhost/import
 | ||||
| */ | ||||
| 
 | ||||
| //-------------------------------------------------------------import data--------------------------------------------------------------------------
 | ||||
| 
 | ||||
| server.use("/import", upload.single('upload'), function (inReq, inRes) { | ||||
| 
 | ||||
|     //console.log(inReq.file);
 | ||||
|     console.log("should have gotten file as post body here"); | ||||
|     var csv = inReq.file.buffer.toString('utf8') | ||||
|     // create a new converter object
 | ||||
|     var c2j = require('csvtojson'); | ||||
|     //var jobj = c2j.fromString(csv).
 | ||||
|     //{headers: "true", delimiter: ",", output: "jsonObj", flatKeys: "true"}
 | ||||
|     c2j({ flatKeys: "true" }).fromString(csv).then( | ||||
|         (x) => { | ||||
|             //console.log(x);
 | ||||
|             //inRes.json(x);
 | ||||
| 
 | ||||
|             //push to db
 | ||||
|             var sql = "SELECT x.message FROM tps.srce_import($$"; | ||||
|             sql += inReq.query.srce; | ||||
|             sql += "$$, $$"  | ||||
|             sql += JSON.stringify(x) | ||||
|             sql += "$$::jsonb) as x(message)" | ||||
|             console.log("sql for insert here"); | ||||
|             //console.log(sql);
 | ||||
| 
 | ||||
|             Postgres.query(sql, (err, res) => { | ||||
| 
 | ||||
|                 //Postgres.end();
 | ||||
| 
 | ||||
|                 if (err === null) { | ||||
|                     inRes.json(res.rows[0]); | ||||
|                     Postgres.end(); | ||||
|                     return; | ||||
|                 } | ||||
|                 inRes.json(err.message); | ||||
|                 //Postgres.end();
 | ||||
|                 //handle error
 | ||||
|             } | ||||
|         ); | ||||
|         } | ||||
|         //const jsonArray = csv().fromFile(csvFilePath);
 | ||||
|         //c2j({ output: "csv" }).fromString(csv).then((jsonObj) => { console.log(jsonObj) });
 | ||||
|         //validate the body contents before pushing to sql?
 | ||||
|     ); | ||||
|     } | ||||
| ); | ||||
| 
 | ||||
| //-------------------------------------------------------------suggest source def--------------------------------------------------------------------------
 | ||||
| 
 | ||||
| server.use("/csv_suggest", upload.single('upload'), function (inReq, inRes) { | ||||
| 
 | ||||
|     //console.log(inReq.file);
 | ||||
|     console.log("should have gotten file as post body here"); | ||||
|     var csv = inReq.file.buffer.toString('utf8') | ||||
|     // create a new converter object
 | ||||
|     var c2j = require('csvtojson'); | ||||
|     //var jobj = c2j.fromString(csv).
 | ||||
|     //{headers: "true", delimiter: ",", output: "jsonObj", flatKeys: "true"}
 | ||||
|     c2j({ flatKeys: "true" }).fromString(csv).then( | ||||
|         (x) => { | ||||
|             //console.log(x);
 | ||||
|             //inRes.json(x);
 | ||||
| 
 | ||||
|             //push to db
 | ||||
|             var sug = {}; | ||||
|             for (var key in x[0]) { | ||||
|                 if (!isNaN(parseFloat(x[0][key])) && isFinite(x[0][key])) { | ||||
|                     if (x[0][key].charAt(0) == "0"){ | ||||
|                         sug[key] = "text"; | ||||
|                     } | ||||
|                     else { | ||||
|                         sug[key] = "numeric"; | ||||
|                     } | ||||
|                 }  | ||||
|                 else if (Date.parse(x[0][key]) > Date.parse('1950-01-01') && Date.parse(x[0][key]) < Date.parse('2050-01-01')) { | ||||
|                     sug[key] = "date"; | ||||
|                 } | ||||
|                 else { | ||||
|                     sug[key] = "text"; | ||||
|                 } | ||||
|             } | ||||
|             console.log(sug); | ||||
|             inRes.json(sug); | ||||
|             //console.log(sql);
 | ||||
|         } | ||||
|         //const jsonArray = csv().fromFile(csvFilePath);
 | ||||
|         //c2j({ output: "csv" }).fromString(csv).then((jsonObj) => { console.log(jsonObj) });
 | ||||
|         //validate the body contents before pushing to sql?
 | ||||
|     ); | ||||
|     } | ||||
| ); | ||||
| 
 | ||||
| 
 | ||||
|     server.get("/", function (inReq, inRes) { | ||||
|         inRes.render("definition", { title: "definition", layout: "main" }); | ||||
|     }) | ||||
| 
 | ||||
|     module.exports = server; | ||||
							
								
								
									
										106
									
								
								static/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								static/index.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,106 @@ | ||||
| <!DOCTYPE html> | ||||
| <html> | ||||
|     <head> | ||||
|         <meta charset="utf-8"> | ||||
|         <meta name="viewport" content="width=device-width, initial-scale=1"> | ||||
|         <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script> | ||||
|         <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular-cookies.js"></script> | ||||
|         <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular-animate.js"></script> | ||||
|         <script src="/static/papa.js"></script> | ||||
|         <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"> | ||||
|         <link rel="stylesheet" href="/static/styles.css"> | ||||
|     </head> | ||||
|     <body> | ||||
| 
 | ||||
|         <div ng-app="DatApp" ng-controller="DatAppController" ng-cloak class="container"> | ||||
| 
 | ||||
| 
 | ||||
|             <div class="row"> | ||||
|                 <form class="well"> | ||||
|                     <div class="form-group"> | ||||
|                         <button class="btn btn-primary" ng-click="save();">Save</button> | ||||
|                         <button class="btn btn-primary" ng-click="load();">Load</button> | ||||
|                     </div> | ||||
|                 </form> | ||||
|             </div> | ||||
| 
 | ||||
|             <div class="row"> | ||||
|                 <form ng-submit="add();" class="well"> | ||||
|                     <div class="form-group"> | ||||
|                         <label>name</label> | ||||
|                         <input class="form-control" type="text" ng-model="currentName"> | ||||
|                     </div> | ||||
|                     <div class="form-group"> | ||||
|                         <button class="btn btn-primary">new one</button> | ||||
|                     </div> | ||||
|                 </form> | ||||
|             </div> | ||||
| 
 | ||||
|             <div class="row"> | ||||
|                 <ul class="list-group"> | ||||
|                     <li class="list-group-item" ng-repeat="member in members"> | ||||
|                         <span>name:</span><strong ng-bind="member.name"></strong> | ||||
|                         <button class="btn btn-danger" ng-click="remove(member);">remove</button> | ||||
|                     </li> | ||||
|                 </ul> | ||||
|             </div> | ||||
|          | ||||
|         </div> | ||||
| 
 | ||||
|         <script> | ||||
|             var DatApp; | ||||
|             DatApp = angular.module("DatApp", []); | ||||
|             DatApp.controller("DatAppController", ["$scope", "$http", function(inScope, inHTTP){ | ||||
|                  | ||||
|                 inScope.currentName = "name"; | ||||
|                 inScope.randomize = function(){ | ||||
|                     inScope.message = Math.random(); | ||||
|                 }; | ||||
|                 inScope.members = []; | ||||
|                 inScope.add = function(){ | ||||
|                     inScope.members.push({ | ||||
|                         name: inScope.currentName, | ||||
|                         id: Math.floor(Math.random()*10000000) | ||||
|                     }); | ||||
|                 }; | ||||
|                 inScope.remove = function(inMember){ | ||||
|                     var i; | ||||
|                     for(i=0; i<inScope.members.length; i++) | ||||
|                     { | ||||
|                         if(inScope.members[i] === inMember){ | ||||
|                             inScope.members.splice(i, 1); | ||||
|                             return; | ||||
|                         } | ||||
|                     } | ||||
|                 }; | ||||
| 
 | ||||
|                 inScope.save = function(){ | ||||
|                     inHTTP({ | ||||
|                         method:"POST", | ||||
|                         url:"/data", | ||||
|                         data:inScope.members | ||||
|                     }) | ||||
|                     .then(function(inSuccess){ | ||||
|                         console.log("done") | ||||
|                     }, function(inFailure){ | ||||
|                         console.log(inFailure); | ||||
|                     }); | ||||
|                 }; | ||||
|                 inScope.load = function(){ | ||||
|                     inHTTP({ | ||||
|                         method:"GET", | ||||
|                         url:"/data" | ||||
|                     }) | ||||
|                     .then(function(inSuccess){ | ||||
|                         inScope.members = inSuccess.data; | ||||
|                         console.log("done"); | ||||
|                     }, function(inFailure){ | ||||
|                         console.log(inFailure); | ||||
|                     }); | ||||
|                 }; | ||||
| 
 | ||||
|             }]); | ||||
|         </script> | ||||
| 
 | ||||
|     </body> | ||||
| </html> | ||||
							
								
								
									
										6
									
								
								static/papa.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								static/papa.js
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										0
									
								
								static/styles.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								static/styles.css
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										24
									
								
								test/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								test/index.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | ||||
| var chai = require('chai'); | ||||
| var chaiHTTP = require('chai-http'); | ||||
| 
 | ||||
| var server = require('../server.js'); | ||||
| var express; | ||||
| 
 | ||||
| var should = chai.should(); | ||||
| chai.use(chaiHTTP); | ||||
| 
 | ||||
| describe("tests", function(){ | ||||
|     before(function(done){ | ||||
|         express = server.listen(7357); | ||||
|         done(); | ||||
|     }); | ||||
|     after(function(done){ | ||||
|         express.close(); | ||||
|         done(); | ||||
|     }); | ||||
|     it("should pass", function(done){ | ||||
|         var test = true; | ||||
|         test.should.equal(true); | ||||
|         done(); | ||||
|     }); | ||||
| }); | ||||
							
								
								
									
										139
									
								
								uploads/5552abe8d6b5ac404a2ed67dfbd9da42
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								uploads/5552abe8d6b5ac404a2ed67dfbd9da42
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,139 @@ | ||||
| Trans. Date,Post Date,Description,Amount,Category | ||||
| 01/02/2018,01/02/2018,"GOOGLE *YOUTUBE VIDEOS G.CO/HELPPAY#CAP0H07TXV",4.26,"Services" | ||||
| 01/02/2018,01/02/2018,"MICROSOFT *ONEDRIVE 800-642-7676 WA",4.26,"Services" | ||||
| 01/03/2018,01/03/2018,"CLE CLINIC PT PMTS 216-445-6249 OHAK2C57F2F0B3",200.00,"Medical Services" | ||||
| 01/04/2018,01/04/2018,"AT&T *PAYMENT 800-288-2020 TX",57.14,"Services" | ||||
| 01/04/2018,01/07/2018,"WWW.KOHLS.COM #0873 MIDDLETOWN OH",-7.90,"Payments and Credits" | ||||
| 01/05/2018,01/07/2018,"PIZZA HUT 007946 STOW OH",9.24,"Restaurants" | ||||
| 01/05/2018,01/07/2018,"SUBWAY 00044289255 STOW OH",10.25,"Restaurants" | ||||
| 01/06/2018,01/07/2018,"ACME NO. 17 STOW OH",103.98,"Supermarkets" | ||||
| 01/06/2018,01/07/2018,"DISCOUNT DRUG MART 32 STOW OH",1.69,"Merchandise" | ||||
| 01/06/2018,01/07/2018,"DISCOUNT DRUG MART 32 STOW OH",2.19,"Merchandise" | ||||
| 01/09/2018,01/09/2018,"CIRCLE K 05416 STOW OH00947R",3.94,"Gasoline" | ||||
| 01/09/2018,01/09/2018,"CIRCLE K 05416 STOW OH00915R",52.99,"Gasoline" | ||||
| 01/13/2018,01/13/2018,"AUTOZONE #0722 STOW OH",85.36,"Automotive" | ||||
| 01/13/2018,01/13/2018,"DISCOUNT DRUG MART 32 STOW OH",26.68,"Merchandise" | ||||
| 01/13/2018,01/13/2018,"EL CAMPESINO STOW OH",6.50,"Restaurants" | ||||
| 01/13/2018,01/13/2018,"TARGET STOW OH",197.90,"Merchandise" | ||||
| 01/14/2018,01/14/2018,"DISCOUNT DRUG MART 32 STOW OH",13.48,"Merchandise" | ||||
| 01/15/2018,01/15/2018,"TARGET.COM * 800-591-3869 MN",22.41,"Merchandise" | ||||
| 01/16/2018,01/16/2018,"BUFFALO WILD WINGS KENT KENT OH",63.22,"Restaurants" | ||||
| 01/16/2018,01/16/2018,"PARTA - KCG KENT OH",4.00,"Government Services" | ||||
| 01/16/2018,01/16/2018,"REMEMBERNHU 402-935-7733 IA",60.00,"Services" | ||||
| 01/16/2018,01/16/2018,"TARGET.COM * 800-591-3869 MN",44.81,"Merchandise" | ||||
| 01/16/2018,01/16/2018,"TREE CITY COFFEE & PASTR KENT OH",17.75,"Restaurants" | ||||
| 01/17/2018,01/17/2018,"BESTBUYCOM805526794885 888-BESTBUY MN",343.72,"Merchandise" | ||||
| 01/19/2018,01/19/2018,"DISCOUNT DRUG MART 32 STOW OH",5.98,"Merchandise" | ||||
| 01/19/2018,01/19/2018,"U-HAUL OF KENT-STOW KENT OH",15.88,"Travel/ Entertainment" | ||||
| 01/19/2018,01/19/2018,"WALMART GROCERY 800-966-6546 AR",5.99,"Supermarkets" | ||||
| 01/19/2018,01/19/2018,"WALMART GROCERY 800-966-6546 AR",17.16,"Supermarkets" | ||||
| 01/19/2018,01/19/2018,"WALMART GROCERY 800-966-6546 AR",500.97,"Supermarkets" | ||||
| 01/20/2018,01/20/2018,"GOOGLE *GOOGLE PLAY G.CO/HELPPAY#CAP0HFFS7W",2.12,"Services" | ||||
| 01/20/2018,01/20/2018,"LOWE'S OF STOW, OH. STOW OH",256.48,"Home Improvement" | ||||
| 01/22/2018,01/22/2018,"HOBBY LOBBY #405 STOW OHITEM TRANSFERRED FROM PREV ACCOUNT",38.49,"Merchandise" | ||||
| 01/23/2018,01/23/2018,"CASHBACK BONUS REDEMPTION PYMT/STMT CRDT",-32.20,"Awards and Rebate Credits" | ||||
| 01/23/2018,01/23/2018,"INTERNET PAYMENT - THANK YOU",-2394.51,"Payments and Credits" | ||||
| 01/27/2018,01/27/2018,"GIANT-EAGLE #4096 STOW OH",67.81,"Supermarkets" | ||||
| 01/27/2018,01/27/2018,"OFFICEMAX/OFFICE DEPOT63 STOW OH",21.06,"Merchandise" | ||||
| 01/27/2018,01/27/2018,"TARGET STOW OH",71.00,"Merchandise" | ||||
| 01/29/2018,01/29/2018,"NETFLIX.COM NETFLIX.COM CA19899514437",14.93,"Services" | ||||
| 01/30/2018,01/30/2018,"PARTA - KCG KENT OH",1.00,"Government Services" | ||||
| 01/30/2018,01/30/2018,"SPEEDWAY 09303 KEN KENT OH",46.57,"Gasoline" | ||||
| 01/30/2018,01/30/2018,"SQ *TWISTED MELTZ KENT OH0002305843011416898511",16.87,"Restaurants" | ||||
| 01/30/2018,01/30/2018,"TARGET STOW OH",49.37,"Merchandise" | ||||
| 01/31/2018,01/31/2018,"TARGET STOW OH",4.14,"Merchandise" | ||||
| 01/31/2018,01/31/2018,"TARGET STREETSBORO OH",14.28,"Merchandise" | ||||
| 01/31/2018,02/01/2018,"TARGET STOW OH",-21.34,"Payments and Credits" | ||||
| 01/31/2018,02/01/2018,"TARGET STREETSBORO OH",-9.60,"Payments and Credits" | ||||
| 02/01/2018,02/01/2018,"EL CAMPESINO STOW OH",42.24,"Restaurants" | ||||
| 02/02/2018,02/02/2018,"CASH ADVANCE FEE",5.00,"Fees" | ||||
| 02/02/2018,02/02/2018,"GOOGLE *ASCIIFLOW.COM G.CO/HELPPAY#CAP0HQTYN5",5.00,"Cash Advances" | ||||
| 02/03/2018,02/03/2018,"TARGET STREETSBORO OH",71.69,"Merchandise" | ||||
| 02/03/2018,02/07/2018,"SAMS CLUB - #4750 CUYAHOGA FALLOH",371.90,"Warehouse Clubs" | ||||
| 02/04/2018,02/04/2018,"ACME NO. 17 STOW OH",8.98,"Supermarkets" | ||||
| 02/04/2018,02/04/2018,"MICROSOFT *ONEDRIVE 800-642-7676 WA",4.26,"Services" | ||||
| 02/06/2018,02/06/2018,"MINIMUM INTEREST CHARGE FEE",0.50,"Fees" | ||||
| 02/06/2018,02/07/2018,"BP#954778736210 7-ELEVEN STOW OH",52.80,"Gasoline" | ||||
| 02/06/2018,02/07/2018,"CVS/PHARMACY #08932 TWINSBURG OH",13.87,"Merchandise" | ||||
| 02/07/2018,02/07/2018,"AT&T *PAYMENT 800-288-2020 TXX51Z5QX7SMT2U01",57.14,"Services" | ||||
| 02/07/2018,02/07/2018,"TOYS R US #9203 CUYAHOGA FALLOH",193.32,"Merchandise" | ||||
| 02/08/2018,02/08/2018,"GIANT-EAGLE #4096 STOW OH",66.13,"Supermarkets" | ||||
| 02/08/2018,02/08/2018,"TARGET STOW OH",121.32,"Merchandise" | ||||
| 02/09/2018,02/09/2018,"GUIDOS ORIGINAL PIZZA KENT OH",11.75,"Restaurants" | ||||
| 02/09/2018,02/09/2018,"MARATHON PETRO73601 TWINSBURG OH",44.30,"Gasoline" | ||||
| 02/10/2018,02/10/2018,"RSVP NO. 36 STOW OH",14.43,"Supermarkets" | ||||
| 02/10/2018,02/10/2018,"TARGET STOW OH",77.90,"Merchandise" | ||||
| 02/11/2018,02/11/2018,"SUBWAY 00044289255 STOW OH",21.00,"Restaurants" | ||||
| 02/13/2018,02/13/2018,"CHICK-FIL-A #02197 CUYAHOGA FLS OH",12.79,"Restaurants" | ||||
| 02/13/2018,02/13/2018,"IN *MR. BULKY'S FOODS AKRON OHAJ16V8Q6",3.39,"Supermarkets" | ||||
| 02/13/2018,02/13/2018,"TARGET CUYAHOGA FALLOH",5.33,"Supermarkets" | ||||
| 02/14/2018,02/14/2018,"DISCOUNT DRUG MART 32 STOW OH",4.29,"Merchandise" | ||||
| 02/14/2018,02/14/2018,"HANDELS ICE CREAM STOW STOW OH",7.95,"Supermarkets" | ||||
| 02/15/2018,02/15/2018,"BATH&BODY STOW OH",47.19,"Merchandise" | ||||
| 02/15/2018,02/15/2018,"TARGET STOW OH",76.35,"Merchandise" | ||||
| 02/17/2018,02/17/2018,"EL CAMPESINO STOW OH",6.50,"Restaurants" | ||||
| 02/17/2018,02/17/2018,"WALMART GROCERY 800-966-6546 AR",461.36,"Supermarkets" | ||||
| 02/18/2018,02/18/2018,"ACME NO. 17 STOW OH",32.68,"Supermarkets" | ||||
| 02/18/2018,02/18/2018,"CHIPOTLE ONLINE 303-595-4000 CO",20.75,"Restaurants" | ||||
| 02/19/2018,02/19/2018,"GIANT EAGLE #5863 STREETSBORO OH",25.00,"Supermarkets" | ||||
| 02/20/2018,02/20/2018,"REMEMBERNHU 402-935-7733 IA",60.00,"Services" | ||||
| 02/21/2018,02/21/2018,"BP#954635936241 7-ELEVEN STOW OH",30.04,"Gasoline" | ||||
| 02/22/2018,02/22/2018,"CHICK-FIL-A #02197 CUYAHOGA FLS OH",3.19,"Restaurants" | ||||
| 02/22/2018,02/22/2018,"CHICK-FIL-A #02197 CUYAHOGA FLS OH",18.22,"Restaurants" | ||||
| 02/22/2018,02/22/2018,"PET SUPPLIES PLUS #68 STOW OH",45.88,"Merchandise" | ||||
| 02/22/2018,02/22/2018,"TOYS R US #9203 CUYAHOGA FALLOH",21.31,"Merchandise" | ||||
| 02/23/2018,02/23/2018,"SUMMIT CO PARKING GAR AKRON OH",6.00,"Services" | ||||
| 02/24/2018,02/24/2018,"GET GO #3396 STOW OH",26.46,"Gasoline" | ||||
| 02/25/2018,02/25/2018,"DISCOUNT DRUG MART 32 STOW OH",19.70,"Merchandise" | ||||
| 02/25/2018,02/25/2018,"EL CAMPESINO STOW OH",6.50,"Restaurants" | ||||
| 02/25/2018,02/25/2018,"SQ *CORNER CUP COFFEEH STOW OH0001152921507942036274",2.30,"Supermarkets" | ||||
| 02/25/2018,02/25/2018,"TARGET STOW OH",18.49,"Merchandise" | ||||
| 02/28/2018,02/28/2018,"NETFLIX.COM NETFLIX.COM CA20475539512",14.93,"Services" | ||||
| 03/01/2018,03/01/2018,"GIANT-EAGLE #4032 STOW OH",2.99,"Supermarkets" | ||||
| 03/01/2018,03/01/2018,"TARGET STOW OH",72.46,"Merchandise" | ||||
| 03/02/2018,03/02/2018,"LATE FEE",27.00,"Fees" | ||||
| 03/02/2018,03/02/2018,"MICROSOFT *ONEDRIVE 800-642-7676 WA",4.26,"Services" | ||||
| 03/02/2018,03/02/2018,"PIZZA HUT 007946 STOW OH",9.89,"Restaurants" | ||||
| 03/03/2018,03/03/2018,"CASHBACK BONUS REDEMPTION PYMT/STMT CRDT",-23.28,"Awards and Rebate Credits" | ||||
| 03/03/2018,03/03/2018,"INTERNET PAYMENT - THANK YOU",-2451.43,"Payments and Credits" | ||||
| 03/03/2018,03/03/2018,"LOWE'S OF STOW, OH. STOW OH",6.93,"Home Improvement" | ||||
| 03/03/2018,03/07/2018,"WAL-MART SC - #2323 STOW OH",150.32,"Merchandise" | ||||
| 03/04/2018,03/04/2018,"OLD NAVY ON-LINE 800-OLDNAVY OH",13.66,"Merchandise" | ||||
| 03/06/2018,03/07/2018,"MFW BOOKS LLC 5732022000 MO",86.90,"Education" | ||||
| 03/06/2018,03/07/2018,"OLD NAVY ON-LINE 800-OLDNAVY OH",127.46,"Merchandise" | ||||
| 03/08/2018,03/08/2018,"ACME NO. 17 STOW OH",8.58,"Supermarkets" | ||||
| 03/08/2018,03/08/2018,"CHICK-FIL-A #02197 CUYAHOGA FLS OH",2.12,"Restaurants" | ||||
| 03/08/2018,03/08/2018,"EL CAMPESINO STOW OH",6.50,"Restaurants" | ||||
| 03/08/2018,03/08/2018,"SPEEDWAY 03686 496 STOW OH",45.24,"Gasoline" | ||||
| 03/08/2018,03/08/2018,"SWENSONS STOW KENT STOW OH",8.30,"Restaurants" | ||||
| 03/08/2018,03/08/2018,"TOYS R US #9203 CUYAHOGA FALLOH",5.33,"Merchandise" | ||||
| 03/09/2018,03/09/2018,"SPEEDWAY 03686 496 STOW OH",48.29,"Gasoline" | ||||
| 03/10/2018,03/10/2018,"WALMART GROCERY 800-966-6546 AR",522.22,"Supermarkets" | ||||
| 03/11/2018,03/11/2018,"AT&T *PAYMENT 800-288-2020 TXQ8F55RY7SMT2N04",57.14,"Services" | ||||
| 03/11/2018,03/11/2018,"SQ *CORNER CUP COFFEEH STOW OH0002305843011470140810",2.30,"Supermarkets" | ||||
| 03/12/2018,03/12/2018,"MICROSOFT *STORE 800-642-7676 WA",1.06,"Services" | ||||
| 03/15/2018,03/15/2018,"SQ *CORNER CUP COFFEEH STOW OH0002305843011475075512",2.30,"Supermarkets" | ||||
| 03/16/2018,03/16/2018,"ACME NO. 17 STOW OH",15.85,"Supermarkets" | ||||
| 03/16/2018,03/16/2018,"CHIPOTLE 1152 STOW OH",3.85,"Restaurants" | ||||
| 03/16/2018,03/16/2018,"EL CAMPESINO STOW OH",6.50,"Restaurants" | ||||
| 03/16/2018,03/16/2018,"PIZZA HUT 007946 STOW OH",13.98,"Restaurants" | ||||
| 03/17/2018,03/17/2018,"CHIPOTLE ONLINE 303-595-4000 CO",15.75,"Restaurants" | ||||
| 03/17/2018,03/17/2018,"DISCOUNT DRUG MART 32 STOW OH",9.89,"Merchandise" | ||||
| 03/17/2018,03/17/2018,"MFW BOOKS LLC 5732022000 MO",66.75,"Education" | ||||
| 03/18/2018,03/18/2018,"ACME NO. 17 STOW OH",27.78,"Supermarkets" | ||||
| 03/18/2018,03/18/2018,"GIANT-EAGLE #4032 STOW OH",28.34,"Supermarkets" | ||||
| 03/20/2018,03/20/2018,"REMEMBERNHU 402-935-7733 IA",60.00,"Services" | ||||
| 03/20/2018,03/20/2018,"SONLIGHT CURRICULUM LTD 303-730-8193 CO",762.87,"Education" | ||||
| 03/21/2018,03/21/2018,"BP#954635936241 7-ELEVEN STOW OH",8.87,"Gasoline" | ||||
| 03/21/2018,03/21/2018,"DISCOUNT DRUG MART 32 STOW OH",18.07,"Merchandise" | ||||
| 03/21/2018,03/21/2018,"SQ *CORNER CUP COFFEEH STOW OH0002305843011484061091",2.30,"Supermarkets" | ||||
| 03/21/2018,03/21/2018,"TARGET STOW OH",1.95,"Merchandise" | ||||
| 03/21/2018,03/21/2018,"TARGET STOW OH",224.85,"Merchandise" | ||||
| 03/22/2018,03/22/2018,"JUSTICE #0639 STOW OH",16.01,"Merchandise" | ||||
| 03/22/2018,03/22/2018,"SPEEDWAY 03686 496 STOW OH",32.54,"Gasoline" | ||||
| 03/22/2018,03/22/2018,"SQ *TWISTED MELTZ KENT OH0002305843011486528725",6.74,"Restaurants" | ||||
| 03/22/2018,03/22/2018,"TARGET STOW OH",6.60,"Merchandise" | ||||
| 03/25/2018,03/25/2018,"ACME NO. 17 STOW OH",95.42,"Supermarkets" | ||||
| 03/25/2018,03/25/2018,"ASIAN-GREEK CUISINES STOW OH",70.25,"Restaurants" | ||||
| 03/25/2018,03/25/2018,"MARATHON PETRO73601 TWINSBURG OH",11.09,"Gasoline" | ||||
| 03/25/2018,03/25/2018,"SPEEDWAY 09303 KEN KENT OH",53.28,"Gasoline" | ||||
							
								
								
									
										149
									
								
								views/definition.handlebars
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								views/definition.handlebars
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,149 @@ | ||||
| <div ng-app="App" ng-controller="AppController"> | ||||
|     <form ng-submit="Submit()"> | ||||
|         <input type="text" ng-model="Model.name"/> | ||||
|         <input type="text" ng-model="Model.description"/> | ||||
|         <h2>Rows</h2> | ||||
|         <div ng-repeat="Row in Model.schema track by $index"> | ||||
|             <input type="text" ng-model="Row.key"/> | ||||
|             <select ng-model="Row.type" ng-options="v for v in Types"></select> | ||||
|         </div> | ||||
|         <input type="submit"/> | ||||
|     </form> | ||||
|     <form> | ||||
|         <input type="file" data-import-csv class="form-control"> | ||||
|     </form> | ||||
| </div> | ||||
| <script> | ||||
| var App = angular.module("App", []); | ||||
| App.factory("Rows", [function() | ||||
| { | ||||
|     return function(inData) | ||||
|     { | ||||
|         console.log(inData); | ||||
|     }; | ||||
| }]); | ||||
| App.directive("importCsv", ["Rows", function(Rows) | ||||
| { | ||||
| 
 | ||||
|     var directive = {}; | ||||
| 
 | ||||
|     directive.link = function(inScope, inElement, inAttributes){ | ||||
| 
 | ||||
|         function handlerEnter(inEvent){ | ||||
|             if(inEvent){ | ||||
|                 inEvent.preventDefault(); | ||||
|             } | ||||
|             inElement.addClass("Import"); | ||||
|             inEvent.dataTransfer.effectAllowed = 'copy'; | ||||
|             return false; | ||||
|         } | ||||
|          | ||||
|         function handlerDrop(inEvent){ | ||||
|             inElement.removeClass("Import"); | ||||
|             if(inEvent){ | ||||
|                 inEvent.preventDefault(); | ||||
|             } | ||||
|             parse(event.dataTransfer.files[0]); | ||||
|             return false; | ||||
|         } | ||||
|          | ||||
|         function handlerChange(inEvent){ | ||||
|             inEvent.stopImmediatePropagation(); | ||||
|             parse(inEvent.target.files[0]); | ||||
|         } | ||||
|          | ||||
|          | ||||
|         function handlerLeave() | ||||
|         { | ||||
|             inElement.removeClass("Import"); | ||||
|         } | ||||
|          | ||||
|         function parse(inFile) | ||||
|         { | ||||
|             Papa.parse(inFile, { | ||||
|                 complete: function(inCSV) | ||||
|                 { | ||||
|                     Rows(inCSV.data); | ||||
|                     inScope.$apply(); | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
| 
 | ||||
|          | ||||
|         inElement.on("dragenter dragstart dragend dragleave dragover drag drop", function (inEvent) {inEvent.preventDefault();}); | ||||
|         inElement.on('dragenter', handlerEnter); | ||||
|         inElement.on('dragleave', handlerLeave); | ||||
|         inElement.on('drop', handlerDrop); | ||||
|         inElement.on('change', handlerChange); | ||||
|         inElement.on('click', function(inEvent){ | ||||
|             inEvent.stopImmediatePropagation(); | ||||
|              | ||||
|         }) | ||||
|     }; | ||||
|     return directive; | ||||
| }]); | ||||
| App.controller("AppController", ["$scope", "$http", function($scope, $http) | ||||
| { | ||||
|     console.log("init"); | ||||
|     $scope.Types = ["date", "text", "numeric"]; | ||||
|     $scope.Model = { | ||||
|         "name": "DCARD", | ||||
|         "description":"Discover Card", | ||||
|         "type": "csv", | ||||
|         "schema": [ | ||||
|             { | ||||
|                 "key": "Trans. Date", | ||||
|                 "type": "date" | ||||
|             }, | ||||
|             { | ||||
|                 "key": "Post Date", | ||||
|                 "type": "date" | ||||
|             }, | ||||
|             { | ||||
|                 "key": "Description", | ||||
|                 "type": "text" | ||||
|             }, | ||||
|             { | ||||
|                 "key": "Amount", | ||||
|                 "type": "numeric" | ||||
|             }, | ||||
|             { | ||||
|                 "key": "Category", | ||||
|                 "type": "text" | ||||
|             } | ||||
|         ], | ||||
|         "unique_constraint": { | ||||
|             "type": "key", | ||||
|             "fields": [ | ||||
|                 "{Post Date}", | ||||
|                 "{Trans. Date}", | ||||
|                 "{Description}" | ||||
|             ] | ||||
|         } | ||||
|     }; | ||||
|     $scope.Submit = function() | ||||
|     { | ||||
|         console.log($scope.Model); | ||||
| 
 | ||||
|     var req = { | ||||
|     method: 'POST', | ||||
|     url: '/json', | ||||
|     data: $scope.Model | ||||
|     }; | ||||
| 
 | ||||
|     $http(req).then( | ||||
|         function(inSuccess){ | ||||
|             console.log(inSuccess); | ||||
|         }, | ||||
|         function(inFailure) | ||||
|         { | ||||
|             console.log(inFailure); | ||||
|         } | ||||
|     ); | ||||
| 
 | ||||
|     }; | ||||
| }]); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| </script> | ||||
							
								
								
									
										16
									
								
								views/layouts/main.handlebars
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								views/layouts/main.handlebars
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,16 @@ | ||||
| <!DOCTYPE html> | ||||
| <html> | ||||
|     <head> | ||||
|         <meta charset="utf-8"> | ||||
|         <meta name="viewport" content="width=device-width, initial-scale=1"> | ||||
|         <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script> | ||||
|         <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular-cookies.js"></script> | ||||
|         <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular-animate.js"></script> | ||||
|         <script src="/static/papa.js"></script> | ||||
|         <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"> | ||||
|         <link rel="stylesheet" href="/static/styles.css"> | ||||
|     </head> | ||||
|     <body> | ||||
|        {{{body}}} | ||||
|     </body> | ||||
| </html> | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user