This commit is contained in:
unknown 2018-06-23 17:10:20 -04:00
commit a90c1942e1
14 changed files with 781 additions and 0 deletions

5
.env.example Normal file
View File

@ -0,0 +1,5 @@
user=
password=
host=
port=
database=

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
node_modules/*
.env
*.log

26
.vscode/launch.json vendored Normal file
View 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
View File

@ -0,0 +1,2 @@
var server = require('./server');
server.listen(80);

27
package.json Normal file
View 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
View 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
View 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
View 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

File diff suppressed because one or more lines are too long

0
static/styles.css Normal file
View File

24
test/index.js Normal file
View 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();
});
});

View 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
View 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>

View 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>