diff --git a/app/controllers/marketplace.js b/app/controllers/marketplace.js index 5f8083b0b..91e6ee6dc 100644 --- a/app/controllers/marketplace.js +++ b/app/controllers/marketplace.js @@ -27,9 +27,10 @@ var MarketplaceController = Ember.ObjectController.extend({ transactionSelected: isSelected('marketplace.transactions', 'credits', 'debits', 'holds', 'refunds', 'reversals'), orderSelected: isSelected('marketplace.orders', 'orders'), + settlementSelected: isSelected('marketplace.settlements', 'settlement'), + disputeSelected: isSelected('marketplace.disputes', 'dispute'), customerSelected: isSelected('marketplace.customers', 'customer'), fundingInstrumentSelected: isSelected('marketplace.funding_instruments', 'bank_accounts', 'cards'), - disputeSelected: isSelected('marketplace.disputes', 'dispute'), logSelected: isSelected('marketplace.logs', 'log'), invoiceSelected: isSelected('marketplace.invoices', 'invoice'), settingSelected: isSelected('marketplace.settings'), diff --git a/app/controllers/marketplace/settlements.js b/app/controllers/marketplace/settlements.js new file mode 100644 index 000000000..0e82d77ef --- /dev/null +++ b/app/controllers/marketplace/settlements.js @@ -0,0 +1,16 @@ +import Ember from "ember"; + +var MarketplaceSettlementsController = Ember.ObjectController.extend({ + needs: ['marketplace'], + resultsLoader: Ember.computed.oneWay("model"), + actions: { + changeDateFilter: function(startTime, endTime) { + this.get("resultsLoader").setProperties({ + endTime: endTime, + startTime: startTime + }); + }, + } +}); + +export default MarketplaceSettlementsController; diff --git a/app/models/bk/account.coffee b/app/models/bk/account.coffee new file mode 100644 index 000000000..36c12c0d2 --- /dev/null +++ b/app/models/bk/account.coffee @@ -0,0 +1,8 @@ +`import Ember from "ember";` +`import BkAccount from "balanced-addon-models/models/account";` + +Account = BkAccount.extend( + routeName: "account" +) + +`export default Account;` diff --git a/app/models/bk/bank-account.coffee b/app/models/bk/bank-account.coffee index 19188a3c6..bd20b0496 100644 --- a/app/models/bk/bank-account.coffee +++ b/app/models/bk/bank-account.coffee @@ -1,7 +1,7 @@ `import Ember from "ember";` -`import BankAccount from "balanced-addon-models/models/bank-account";` +`import BkBankAccount from "balanced-addon-models/models/bank-account";` -BkBankAccount = BankAccount.extend( +BankAccount = BkBankAccount.extend( ) -`export default BkBankAccount;` +`export default BankAccount;` diff --git a/app/models/bk/settlement.coffee b/app/models/bk/settlement.coffee new file mode 100644 index 000000000..e937db708 --- /dev/null +++ b/app/models/bk/settlement.coffee @@ -0,0 +1,8 @@ +`import Ember from "ember";` +`import BkSettlement from "balanced-addon-models/models/settlement";` + +Settlement = BkSettlement.extend( + routeName: "settlement" +) + +`export default Settlement;` diff --git a/app/models/customer.js b/app/models/customer.js index 2a347ed63..bc4556a45 100644 --- a/app/models/customer.js +++ b/app/models/customer.js @@ -3,6 +3,7 @@ import Model from "./core/model"; import Computed from "balanced-dashboard/utils/computed"; import FundingInstrumentsResultsLoader from "./results-loaders/funding-instruments"; import TransactionsResultsLoader from "./results-loaders/transactions"; +import AccountsResultsLoader from "./results-loaders/accounts"; var CUSTOMER_TYPES = { BUSINESS: 'Business', @@ -73,6 +74,12 @@ var Customer = Model.extend({ }, attributes); return TransactionsResultsLoader.create(attributes); }, + getAccountsLoader: function(attributes) { + attributes = _.extend({ + path: this.get("accounts_uri"), + }, attributes); + return AccountsResultsLoader.create(attributes); + }, type: function() { return (this.get('ein') || this.get('business_name')) ? CUSTOMER_TYPES.BUSINESS : CUSTOMER_TYPES.PERSON; diff --git a/app/models/results-loaders/accounts.js b/app/models/results-loaders/accounts.js new file mode 100644 index 000000000..27c0cfbde --- /dev/null +++ b/app/models/results-loaders/accounts.js @@ -0,0 +1,8 @@ +import BaseResultsLoader from "./base"; +import Account from "../bk/account"; + +var AccountsResultsLoader = BaseResultsLoader.extend({ + resultsType: Account, +}); + +export default AccountsResultsLoader; diff --git a/app/models/results-loaders/settlements.js b/app/models/results-loaders/settlements.js new file mode 100644 index 000000000..98085e166 --- /dev/null +++ b/app/models/results-loaders/settlements.js @@ -0,0 +1,8 @@ +import BaseResultsLoader from "./base"; +import Settlement from "../bk/settlement"; + +var SettlementsResultsLoader = BaseResultsLoader.extend({ + resultsType: Settlement, +}); + +export default SettlementsResultsLoader; diff --git a/app/router.coffee b/app/router.coffee index 24796887c..2c8f5fe07 100644 --- a/app/router.coffee +++ b/app/router.coffee @@ -61,6 +61,9 @@ Router.map -> this.route("customers") this.resource('customer', path: '/customers/:item_id') + this.route("settlements") + this.resource('settlement', path: '/settlements/:item_id') + this.route("disputes") this.resource('dispute', path: '/disputes/:item_id') diff --git a/app/routes/customer.js b/app/routes/customer.js index 38f77a52f..805c95341 100644 --- a/app/routes/customer.js +++ b/app/routes/customer.js @@ -1,5 +1,6 @@ import ModelRoute from "./model"; import Customer from "../models/customer"; +import LegacyResultsLoaderWrapper from "balanced-dashboard/utils/legacy-results-loader-wrapper"; var CustomerRoute = ModelRoute.extend({ title: 'Customer', @@ -8,6 +9,12 @@ var CustomerRoute = ModelRoute.extend({ setupController: function(controller, customer) { this._super(controller, customer); + var store = this.container.lookup("controller:marketplace").get("store"); + store.fetchCollection("account", customer.get("accounts_uri"), { limit: 10 }).then(function(collection) { + var wrapper = LegacyResultsLoaderWrapper.create({collection: collection}); + controller.set("accountsResultsLoader", wrapper); + }); + controller.setProperties({ fundingInstrumentsResultsLoader: customer.getFundingInstrumentsLoader({ limit: 10 diff --git a/app/routes/marketplace/settlements.js b/app/routes/marketplace/settlements.js new file mode 100644 index 000000000..e6f3282b4 --- /dev/null +++ b/app/routes/marketplace/settlements.js @@ -0,0 +1,15 @@ +import AuthRoute from "../auth"; +import LegacyResultsLoaderWrapper from "balanced-dashboard/utils/legacy-results-loader-wrapper"; + +var MarketplaceSettlementsRoute = AuthRoute.extend({ + pageTitle: 'Settlements', + model: function() { + var store = this.container.lookup("controller:marketplace").get("store"); + return store.fetchCollection("settlement", "/settlements", { limit: 50 }).then(function(collection) { + var wrapper = LegacyResultsLoaderWrapper.create({collection: collection}); + return wrapper; + }); + }, +}); + +export default MarketplaceSettlementsRoute; diff --git a/app/routes/settlement.js b/app/routes/settlement.js new file mode 100644 index 000000000..8fce45a16 --- /dev/null +++ b/app/routes/settlement.js @@ -0,0 +1,13 @@ +import ModelRoute from "./model"; +import Settlement from "../models/bk/settlement"; + +var SettlementRoute = ModelRoute.extend({ + title: 'Settlement', + modelObject: Settlement, + marketplaceUri: 'settlements_uri', + setupController: function(controller, customer) { + this._super(controller, customer); + } +}); + +export default SettlementRoute; diff --git a/app/stores/balanced.coffee b/app/stores/balanced.coffee index 8ca9c450a..88460ff12 100644 --- a/app/stores/balanced.coffee +++ b/app/stores/balanced.coffee @@ -4,6 +4,8 @@ BalancedStore = Store.extend( modelMaps: bank_account: "model:bk/bank-account" customer: "model:bk/customer" + account: "model:bk/customer" + settlement: "model:bk/customer" ) `export default BalancedStore;` diff --git a/app/templates/customer.hbs b/app/templates/customer.hbs index 5404e1d15..5e9f845ae 100644 --- a/app/templates/customer.hbs +++ b/app/templates/customer.hbs @@ -35,6 +35,11 @@ {{view "results/embedded-funding-instruments-table" loader=fundingInstrumentsResultsLoader}} +

Accounts

+
+ {{view "results/embedded-funding-instruments-table" loader=accountsResultsLoader}} +
+

Logs

{{view "resource-logs" content=model}} diff --git a/app/templates/marketplace/settlements.hbs b/app/templates/marketplace/settlements.hbs new file mode 100644 index 000000000..cbe4fcda7 --- /dev/null +++ b/app/templates/marketplace/settlements.hbs @@ -0,0 +1,9 @@ +{{view "page-navigations/page-navigation" title="Settlements"}} + + + +
+
+ {{view "results/settlements-table" loader=resultsLoader}} +
+
diff --git a/app/templates/results/grouped-settlement-row.hbs b/app/templates/results/grouped-settlement-row.hbs new file mode 100644 index 000000000..3dbf0e385 --- /dev/null +++ b/app/templates/results/grouped-settlement-row.hbs @@ -0,0 +1,28 @@ + + {{#link-to view.routeName view.item}} + + {{view.displayValue}} + + {{/link-to}} + + + {{#link-to view.routeName view.item}} + + {{view.paymentMethodText}} + + {{/link-to}} + + + {{#link-to view.routeName view.item}} + + {{view.paymentMethodText}} + + {{/link-to}} + + + {{#link-to view.routeName view.item}} + + {{view.amountText}} + + {{/link-to}} + diff --git a/app/templates/results/settlements-table.hbs b/app/templates/results/settlements-table.hbs new file mode 100644 index 000000000..ef525cac8 --- /dev/null +++ b/app/templates/results/settlements-table.hbs @@ -0,0 +1,41 @@ + + + + {{view "results/settlements-transaction-results-dropdown-filter"}} + + Customer + Payment method + + + {{#view "results/results-loader-sort-column-header" resultsLoader=view.loader field="amount" actionName="changeDisputesSort"}} + Amount + {{/view}} + + + + +{{#if view.loader.results.hasNextPage}} + {{view "results/results-load-more" results=view.loader.results columns=view.colspan}} +{{/if}} + + + {{#each dispute in view.loader.results}} + + + {{#view "results/grouped-transactions-table"}} + {{view "results/grouped-settlement-row" item=view.parentView.transaction.dispute}} + {{/view}} + + + {{else}} + + + {{#if view.loader.results.isLoaded}} + No settlements + {{else}} + Loading... + {{/if}} + + + {{/each}} + diff --git a/app/utils/legacy-results-loader-wrapper.coffee b/app/utils/legacy-results-loader-wrapper.coffee new file mode 100644 index 000000000..5e6bb0e23 --- /dev/null +++ b/app/utils/legacy-results-loader-wrapper.coffee @@ -0,0 +1,28 @@ +`import Ember from "ember";` + +LegacyResultsLoaderWrapper = Ember.Object.extend( + results: Ember.computed.reads("collection") + isLoading: Ember.computed.reads("collection.isLoading") + + loadNextPage: -> + @get("collection").loadNextPage() +) + +LegacyResultsLoaderWrapper.reopenClass( + generateMethod: (methodName) -> + return (attributes) -> + LegacyResultsLoaderWrapper.createForCollection(=> + return @[methodName](attributes || {}) + ) + + createForCollection: (initializer) -> + loader = @create(collection: []) + if Ember.isArray(initializer) + loader.set("collection", initializer) + else + initializer().then (collection) -> + loader.set("collection", collection) + loader +) + +`export default LegacyResultsLoaderWrapper;` diff --git a/app/views/results/settlements-table.js b/app/views/results/settlements-table.js new file mode 100644 index 000000000..8bb78ee20 --- /dev/null +++ b/app/views/results/settlements-table.js @@ -0,0 +1,8 @@ +import ResultsTableView from "./results-table"; + +var SettlementsResultsView = ResultsTableView.extend({ + classNames: 'settlements', + templateName: 'results/settlements-table' +}); + +export default SettlementsResultsView; diff --git a/app/views/results/settlements-transaction-results-dropdown-filter.js b/app/views/results/settlements-transaction-results-dropdown-filter.js new file mode 100644 index 000000000..d040c54d2 --- /dev/null +++ b/app/views/results/settlements-transaction-results-dropdown-filter.js @@ -0,0 +1,24 @@ +import ResultsDropdownFilterView from "./results-dropdown-filter"; +import { defineFilter } from "./results-dropdown-filter"; + +var SettlementsTransactionResultsDropdownFilterView = ResultsDropdownFilterView.extend({ + toggleText: "Status", + filters: function() { + return [ + defineFilter("All", null, true), + defineFilter("Needs attention & Under review", ["pending"]), + defineFilter("Won", ["won"]), + defineFilter("Lost", ["lost"]) + ]; + }.property(), + + actions: { + setFilter: function(filterLink) { + var controller = this.get('controller'); + controller.send('changeDisputeStatusFilter', filterLink.value); + this.toggleSelected(filterLink); + } + } +}); + +export default SettlementsTransactionResultsDropdownFilterView; diff --git a/app/views/sidebar/marketplace-sidebar.js b/app/views/sidebar/marketplace-sidebar.js index 0d78e061f..1b30b7164 100644 --- a/app/views/sidebar/marketplace-sidebar.js +++ b/app/views/sidebar/marketplace-sidebar.js @@ -6,15 +6,10 @@ var SIDEBAR_ITEMS = [{ routeName: "marketplace.orders", isSelectedBinding: "controller.controllers.marketplace.paymentSelected", }, { - linkText: "Customers", - linkIcon: "icon-customers", - routeName: "marketplace.customers", - isSelectedBinding: "controller.controllers.marketplace.customerSelected" -}, { - linkText: "Payment methods", - linkIcon: "icon-card", - routeName: "marketplace.funding_instruments", - isSelectedBinding: "controller.controllers.marketplace.fundingInstrumentSelected" + linkText: "Settlements", + linkIcon: "icon-settlements", + routeName: "marketplace.settlements", + isSelectedBinding: "controller.controllers.marketplace.settlementSelected", }, { linkText: "Disputes", linkIcon: "icon-disputes", @@ -26,6 +21,16 @@ var SIDEBAR_ITEMS = [{ linkIcon: "icon-logs", routeName: "marketplace.logs", isSelectedBinding: "controller.controllers.marketplace.logSelected" +}, { + linkText: "Customers", + linkIcon: "icon-customers", + routeName: "marketplace.customers", + isSelectedBinding: "controller.controllers.marketplace.customerSelected" +}, { + linkText: "Payment methods", + linkIcon: "icon-card", + routeName: "marketplace.funding_instruments", + isSelectedBinding: "controller.controllers.marketplace.fundingInstrumentSelected" }, { linkText: "Account statements", linkIcon: "icon-invoices", diff --git a/bower.json b/bower.json index 543994980..bbf8b07df 100644 --- a/bower.json +++ b/bower.json @@ -13,7 +13,7 @@ "ember-validations": "lcoq/ember-validations", "google-code-prettify": "1.0.0", "handlebars": "~1.3.0", - "strapped": "0.3.14", + "strapped": "0.3.15", "jquery-csv": "", "jquery-hotkeys": "jeresig/jquery.hotkeys", "jquery.cookie": "1.3.1",