diff --git a/.idea/deployment.xml b/.idea/deployment.xml new file mode 100644 index 0000000..21ffcc4 --- /dev/null +++ b/.idea/deployment.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/sshConfigs.xml b/.idea/sshConfigs.xml new file mode 100644 index 0000000..63d62d8 --- /dev/null +++ b/.idea/sshConfigs.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/webServers.xml b/.idea/webServers.xml new file mode 100644 index 0000000..554ca6a --- /dev/null +++ b/.idea/webServers.xml @@ -0,0 +1,14 @@ + + + + + + \ No newline at end of file diff --git a/apiV1GridLoanFullOverview.go b/apiV1GridLoanFullOverview.go index 6f5ec0e..a3c5672 100644 --- a/apiV1GridLoanFullOverview.go +++ b/apiV1GridLoanFullOverview.go @@ -44,3 +44,16 @@ func apiV1GridLoanFullOverview(w http.ResponseWriter, r *http.Request, ss *loan. apiV1SendJson(data, w, r, ss) } } + +func apiV1GridListLoanOverview(w http.ResponseWriter, r *http.Request, ss *loan.Session) { + input := loan.KdQueryInput{} + e := input.ReadFromHttpRequest(r) + if e != nil { + apiV1Client404Error(w, r, ss) + return + } + filter := loan.OverViewListFilter{KdQueryInput: input} + ret := filter.Retrieve() + apiV1SendJson(ret, w, r, ss) + +} diff --git a/apiV1LoanSingle.go b/apiV1LoanSingle.go index c88ecb3..b0974fb 100644 --- a/apiV1LoanSingle.go +++ b/apiV1LoanSingle.go @@ -46,6 +46,8 @@ func apiV1LoanSinglePostBasic(w http.ResponseWriter, r *http.Request, ss *loan.S l.Status = input.Status l.Amount = input.Amount l.Item = input.Item + l.Lender = input.Lender + l.LenderLoanNumber = input.LenderLoanNumber l.Rating = input.Rating l.Settlement = input.Settlement l.Description = input.Description diff --git a/apiV1PayInList.go b/apiV1PayInList.go index f14dcda..ee14426 100644 --- a/apiV1PayInList.go +++ b/apiV1PayInList.go @@ -7,7 +7,7 @@ import ( "net/http" ) -func decodePayInFilter(r *http.Request) (ret loan.PayInListFilter, e error) { +func decodePayInFilter(r *http.Request) (ret loan.PayInListFilterOld, e error) { decoder := json.NewDecoder(r.Body) //decoder.DisallowUnknownFields() e = decoder.Decode(&ret) @@ -35,3 +35,15 @@ func apiV1PayInList(w http.ResponseWriter, r *http.Request, ss *loan.Session) { apiV1SendJson(ret, w, r, ss) } + +func apiV1FilteredPayInList(w http.ResponseWriter, r *http.Request, ss *loan.Session) { + input := loan.KdQueryInput{} + e := input.ReadFromHttpRequest(r) + if e != nil { + apiV1Client404Error(w, r, ss) + return + } + payInListFilter := loan.PayInListFilter{KdQueryInput: input} + ret := payInListFilter.Retrieve() + apiV1SendJson(ret, w, r, ss) +} diff --git a/apiV1Payout.go b/apiV1Payout.go new file mode 100644 index 0000000..17da6d4 --- /dev/null +++ b/apiV1Payout.go @@ -0,0 +1,301 @@ +package main + +import ( + "biukop.com/sfm/loan" + "encoding/json" + log "github.com/sirupsen/logrus" + "net/http" + "time" +) + +func decodeJsonPayOutEdit(r *http.Request) (ret loan.PayOut, e error) { + decoder := json.NewDecoder(r.Body) + //decoder.DisallowUnknownFields() + e = decoder.Decode(&ret) + if e != nil { + log.Error("failed decoding PayIn for updating", e.Error()) + return + } + return +} + +func apiV1PayOutPost(w http.ResponseWriter, r *http.Request, ss *loan.Session) { + input, e := decodeJsonPayOutEdit(r) + log.Println(input) + + if e != nil { + apiV1Client404Error(w, r, ss) + return + } else { + lowerBound, _ := time.Parse("2006-01-02", "1900-01-01") + if input.Ts.Before(lowerBound) { + input.Ts = time.Now() + } + e = input.WriteWithRewardIds() + if e != nil { + log.Error("cannot save payout meta", e.Error()) + apiV1Client404Error(w, r, ss) + } else { + + poEx := loan.PayOutEx{} + e = poEx.Read(input.Id) + if e != nil { + log.Error("weird failed to read PayInEx after successfully write PayIn", input, poEx, e.Error()) + apiV1Client404Error(w, r, ss) + } else { + apiV1SendJson(poEx, w, r, ss) + } + } + + } +} + +func apiV1PayOutPrepared(w http.ResponseWriter, r *http.Request, ss *loan.Session) { + input, e := decodeJsonPayOutEdit(r) + log.Println(input) + + if e != nil { + apiV1Client404Error(w, r, ss) + return + } + + po := loan.PayOut{} + e = po.Read(input.Id) + if e != nil { + apiV1Client404Error(w, r, ss) + return + } + + po.Prepared = input.Prepared + po.Approved = "" + po.Paid = "" + po.PayDate, _ = time.Parse("2006-01-02", "1900-01-01") + po.PayAmount = 0 + + e = po.Write() + if e != nil { + apiV1Server500Error(w, r) + return + } + + ret := loan.PayOutEx{} + e = ret.Read(input.Id) + if e != nil { + apiV1Server500Error(w, r) + return + } + + apiV1SendJson(ret, w, r, ss) +} + +func apiV1PayOutUnprepared(w http.ResponseWriter, r *http.Request, ss *loan.Session) { + input, e := decodeJsonPayOutEdit(r) + log.Println(input) + + if e != nil { + apiV1Client404Error(w, r, ss) + return + } + + po := loan.PayOut{} + e = po.Read(input.Id) + if e != nil { + apiV1Client404Error(w, r, ss) + return + } + + po.Prepared = "" + po.Approved = "" + po.Paid = "" + po.PayDate, _ = time.Parse("2006-01-02", "1900-01-01") + po.PayAmount = 0 + + e = po.Write() + if e != nil { + apiV1Server500Error(w, r) + return + } + + ret := loan.PayOutEx{} + e = ret.Read(input.Id) + if e != nil { + apiV1Server500Error(w, r) + return + } + + apiV1SendJson(ret, w, r, ss) +} + +func apiV1PayOutApproved(w http.ResponseWriter, r *http.Request, ss *loan.Session) { + input, e := decodeJsonPayOutEdit(r) + log.Println(input) + + if e != nil { + apiV1Client404Error(w, r, ss) + return + } + + po := loan.PayOut{} + e = po.Read(input.Id) + if e != nil { + apiV1Client404Error(w, r, ss) + return + } + + if po.Prepared == "" { + log.Error("try to approve unprepared payout") + apiV1Client403Error(w, r, ss) + return + } + + po.Approved = input.Approved + po.Paid = "" + po.PayDate, _ = time.Parse("2006-01-02", "1900-01-01") + po.PayAmount = 0 + + e = po.Write() + if e != nil { + apiV1Server500Error(w, r) + return + } + + ret := loan.PayOutEx{} + e = ret.Read(input.Id) + if e != nil { + log.Error("can not approve payout ", e) + apiV1Server500Error(w, r) + return + } + + apiV1SendJson(ret, w, r, ss) +} + +func apiV1PayOutUnapproved(w http.ResponseWriter, r *http.Request, ss *loan.Session) { + input, e := decodeJsonPayOutEdit(r) + log.Println(input) + + if e != nil { + apiV1Client404Error(w, r, ss) + return + } + + po := loan.PayOut{} + e = po.Read(input.Id) + if e != nil { + apiV1Client404Error(w, r, ss) + return + } + + if po.Approved == "" { + log.Error("try to unapprove draft payout") + apiV1Client403Error(w, r, ss) + return + } + + po.Approved = "" + po.Paid = "" + po.PayDate, _ = time.Parse("2006-01-02", "1900-01-01") + po.PayAmount = 0 + + e = po.Write() + if e != nil { + apiV1Server500Error(w, r) + return + } + + ret := loan.PayOutEx{} + e = ret.Read(input.Id) + if e != nil { + log.Error("can not approve payout ", e) + apiV1Server500Error(w, r) + return + } + + apiV1SendJson(ret, w, r, ss) +} + +func apiV1PayOutPaid(w http.ResponseWriter, r *http.Request, ss *loan.Session) { + input, e := decodeJsonPayOutEdit(r) + log.Println(input) + + if e != nil { + apiV1Client404Error(w, r, ss) + return + } + + po := loan.PayOut{} + e = po.Read(input.Id) + if e != nil { + apiV1Client404Error(w, r, ss) + return + } + + if po.Approved == "" || po.Prepared == "" { + log.Error("try to pay draft payout", po) + apiV1Client403Error(w, r, ss) + return + } + + po.Paid = input.Paid + po.PayDate = input.PayDate + po.PayAmount = input.PayAmount + + e = po.Write() + if e != nil { + apiV1Server500Error(w, r) + return + } + + ret := loan.PayOutEx{} + e = ret.Read(input.Id) + if e != nil { + log.Error("can not approve payout ", e) + apiV1Server500Error(w, r) + return + } + + apiV1SendJson(ret, w, r, ss) +} + +func apiV1PayOutUnpaid(w http.ResponseWriter, r *http.Request, ss *loan.Session) { + input, e := decodeJsonPayOutEdit(r) + log.Println(input) + + if e != nil { + apiV1Client404Error(w, r, ss) + return + } + + po := loan.PayOut{} + e = po.Read(input.Id) + if e != nil { + apiV1Client404Error(w, r, ss) + return + } + + if po.Approved == "" || po.Prepared == "" || po.Paid == "" { + log.Error("try to un-pay draft payout", po) + apiV1Client403Error(w, r, ss) + return + } + + po.Paid = "" + po.PayDate, _ = time.Parse("2006-01-02", "1900-01-01") + po.PayAmount = 0 + + e = po.Write() + if e != nil { + apiV1Server500Error(w, r) + return + } + + ret := loan.PayOutEx{} + e = ret.Read(input.Id) + if e != nil { + log.Error("can not approve payout ", e) + apiV1Server500Error(w, r) + return + } + + apiV1SendJson(ret, w, r, ss) +} diff --git a/apiV1PayoutEx.go b/apiV1PayoutEx.go index b2b5b80..cc50d09 100644 --- a/apiV1PayoutEx.go +++ b/apiV1PayoutEx.go @@ -2,6 +2,7 @@ package main import ( "biukop.com/sfm/loan" + "database/sql" log "github.com/sirupsen/logrus" "net/http" "strconv" @@ -17,8 +18,13 @@ func apiV1PayOutExGet(w http.ResponseWriter, r *http.Request, ss *loan.Session) } e = ret.Read(int64(id)) if e != nil { + if e == sql.ErrNoRows { + apiV1Client404Error(w, r, ss) + return + } log.Error("failed to read PayOutEx", strId, e.Error()) apiV1Server500Error(w, r) + return } apiV1SendJson(ret, w, r, ss) diff --git a/apiV1PeopleList.go b/apiV1PeopleList.go index 688baab..9e5c435 100644 --- a/apiV1PeopleList.go +++ b/apiV1PeopleList.go @@ -61,6 +61,7 @@ func apiV1PeoplePost(w http.ResponseWriter, r *http.Request, ss *loan.Session) { p.First = input.First p.Last = input.Last + p.Middle = input.Middle p.Display = input.Display p.Enabled = input.Enabled diff --git a/apiV1Reward.go b/apiV1Reward.go index 1e1c6cb..f990593 100644 --- a/apiV1Reward.go +++ b/apiV1Reward.go @@ -30,12 +30,12 @@ func apiV1RewardPost(w http.ResponseWriter, r *http.Request, ss *loan.Session) { return } else { re.Id = input.Id - re.PayoutId = input.PayoutId + re.PayOutId = input.PayOutId re.Description = input.Description re.LoanId = input.LoanId re.Amount = input.Amount - re.From = input.From - re.To = input.To + re.FromId = input.FromId + re.ToId = input.ToId re.Ts = input.Ts e = re.Write() if e != nil { @@ -64,3 +64,16 @@ func apiV1RewardDelete(w http.ResponseWriter, r *http.Request, ss *loan.Session) } apiV1SendJson(id64, w, r, ss) } + +func apiV1RewardExListPost(w http.ResponseWriter, r *http.Request, ss *loan.Session) { + input := loan.KdQueryInput{} + e := input.ReadFromHttpRequest(r) + if e != nil { + apiV1Client404Error(w, r, ss) + return + } + rewardListFilter := loan.RewardExListFilter{KdQueryInput: input} + ret := rewardListFilter.Retrieve() + apiV1SendJson(ret, w, r, ss) + return +} diff --git a/apiV1User.go b/apiV1User.go index c7eb5c9..eaf47ac 100644 --- a/apiV1User.go +++ b/apiV1User.go @@ -163,3 +163,13 @@ func apiV1UserExGet(w http.ResponseWriter, r *http.Request, ss *loan.Session) { } apiV1SendJson(ret, w, r, ss) } + +func apiV1UserExList(w http.ResponseWriter, r *http.Request, ss *loan.Session) { + filter := "" + keys, ok := r.URL.Query()["filter"] + if ok && len(keys) >= 1 { + filter = keys[0] + } + data := loan.GetUserExList(filter) + apiV1SendJson(data, w, r, ss) +} diff --git a/apiv1.go b/apiv1.go index f0029cc..fd1f9f2 100644 --- a/apiv1.go +++ b/apiv1.go @@ -35,7 +35,8 @@ func setupApiV1Handler() []apiV1HandlerMap { {"GET", "chart/past-year-monthly", apiV1ChartPastYearMonthly}, {"GET", "chart/recent-10-loans", apiV1ChartRecent10Loans}, {"GET", "chart/top-broker", apiV1ChartTopBroker}, - {"POST", "grid/loan/full-loan-overview", apiV1GridLoanFullOverview}, + //{"POST", "grid/loan/full-loan-overview", apiV1GridLoanFullOverview}, + {"POST", "grid/loan/full-loan-overview", apiV1GridListLoanOverview}, {"GET", "chart/reward-vs-income-monthly", apiV1ChartRewardVsIncomeMonthly}, {"GET", "loan/", apiV1LoanSingleGet}, {"DELETE", "loan/", apiV1LoanSingleDelete}, @@ -53,6 +54,7 @@ func setupApiV1Handler() []apiV1HandlerMap { {"POST", "user-enable/", apiV1UserEnable}, {"GET", "user-ex/", apiV1UserExGet}, + {"GET", "user-ex-list/", apiV1UserExList}, {"GET", "broker/", apiV1BrokerGet}, {"POST", "broker/", apiV1BrokerPost}, @@ -66,12 +68,14 @@ func setupApiV1Handler() []apiV1HandlerMap { {"POST", "reward/", apiV1RewardPost}, {"DELETE", "reward/", apiV1RewardDelete}, {"GET", "people-list/", apiV1PeopleList}, + {"GET", "broker-list/", apiV1BrokerList}, {"POST", "sync-people/", apiV1SyncPeople}, {"POST", "payIn/", apiV1PayInPost}, {"DELETE", "payIn/", apiV1PayInDelete}, {"POST", "pay-in-list/", apiV1PayInList}, + {"POST", "pay-in-filtered-list/", apiV1FilteredPayInList}, {"GET", "user-reward/", apiV1UserReward}, {"GET", "login-available/", apiV1LoginAvailable}, @@ -95,6 +99,16 @@ func setupApiV1Handler() []apiV1HandlerMap { {"GET", "payout-ex/", apiV1PayOutExGet}, + {"POST", "reward-ex-list/", apiV1RewardExListPost}, + + {"POST", "payout/", apiV1PayOutPost}, + {"POST", "payout-prepared/", apiV1PayOutPrepared}, + {"POST", "payout-unprepared/", apiV1PayOutUnprepared}, + {"POST", "payout-approved/", apiV1PayOutApproved}, + {"POST", "payout-unapproved/", apiV1PayOutUnapproved}, + {"POST", "payout-paid/", apiV1PayOutPaid}, + {"POST", "payout-unpaid/", apiV1PayOutUnpaid}, + {"GET", "login", apiV1DumpRequest}, } } else { //production @@ -106,7 +120,8 @@ func setupApiV1Handler() []apiV1HandlerMap { {"GET", "chart/past-year-monthly", apiV1ChartPastYearMonthly}, {"GET", "chart/recent-10-loans", apiV1ChartRecent10Loans}, {"GET", "chart/top-broker", apiV1ChartTopBroker}, - {"POST", "grid/loan/full-loan-overview", apiV1GridLoanFullOverview}, + //{"POST", "grid/loan/full-loan-overview", apiV1GridLoanFullOverview}, + {"POST", "grid/loan/full-loan-overview", apiV1GridListLoanOverview}, {"GET", "chart/reward-vs-income-monthly", apiV1ChartRewardVsIncomeMonthly}, {"GET", "loan/", apiV1LoanSingleGet}, {"DELETE", "loan/", apiV1LoanSingleDelete}, @@ -124,6 +139,7 @@ func setupApiV1Handler() []apiV1HandlerMap { {"POST", "user-enable/", apiV1UserEnable}, {"GET", "user-ex/", apiV1UserExGet}, + {"GET", "user-ex-list/", apiV1UserExList}, {"GET", "broker/", apiV1BrokerGet}, {"POST", "broker/", apiV1BrokerPost}, @@ -138,12 +154,14 @@ func setupApiV1Handler() []apiV1HandlerMap { {"POST", "reward/", apiV1RewardPost}, {"DELETE", "reward/", apiV1RewardDelete}, {"GET", "people-list", apiV1PeopleList}, + {"GET", "broker-list/", apiV1BrokerList}, {"POST", "sync-people/", apiV1SyncPeople}, {"POST", "payIn/", apiV1PayInPost}, {"DELETE", "payIn/", apiV1PayInDelete}, {"POST", "pay-in-list/", apiV1PayInList}, + {"POST", "pay-in-filtered-list/", apiV1FilteredPayInList}, {"GET", "user-reward/", apiV1UserReward}, {"GET", "login-available/", apiV1LoginAvailable}, @@ -167,6 +185,16 @@ func setupApiV1Handler() []apiV1HandlerMap { {"GET", "payout-ex/", apiV1PayOutExGet}, + {"POST", "reward-ex-list/", apiV1RewardExListPost}, + + {"POST", "payout/", apiV1PayOutPost}, + {"POST", "payout-prepared/", apiV1PayOutPrepared}, + {"POST", "payout-unprepared/", apiV1PayOutUnprepared}, + {"POST", "payout-approved/", apiV1PayOutApproved}, + {"POST", "payout-unapproved/", apiV1PayOutUnapproved}, + {"POST", "payout-paid/", apiV1PayOutPaid}, + {"POST", "payout-unpaid/", apiV1PayOutUnpaid}, + {"GET", "login", apiV1EmptyResponse}, } }