From d7e41058841d213f4f194f2bb29b666115322e9b Mon Sep 17 00:00:00 2001 From: Kyungmin Kim Date: Fri, 23 Jan 2015 09:26:59 -0800 Subject: [PATCH] Fixes #1631: Creating a debit automatically creates customers and order --- app/models/credit.js | 9 +--- app/models/customer.js | 9 ++++ app/models/debit.js | 5 ++ .../debit-card-transaction-factory.js | 46 +++++++++++++++---- app/serializers/transaction.js | 18 ++++++++ .../modals/card-debit-create-modal.hbs | 16 +++++-- app/views/form-fields/email-form-field.js | 8 ++++ app/views/modals/card-debit-create-modal.js | 4 +- 8 files changed, 95 insertions(+), 20 deletions(-) create mode 100644 app/serializers/transaction.js create mode 100644 app/views/form-fields/email-form-field.js diff --git a/app/models/credit.js b/app/models/credit.js index 5a0c2b3a1..d02785092 100644 --- a/app/models/credit.js +++ b/app/models/credit.js @@ -1,7 +1,7 @@ import Ember from "ember"; import Computed from "balanced-dashboard/utils/computed"; import Transaction from "./transaction"; -import Rev1Serializer from "../serializers/rev1"; +import TransactionSerializer from "../serializers/transaction"; import Model from "./core/model"; import Utils from "balanced-dashboard/lib/utils"; @@ -70,7 +70,7 @@ var Credit = Transaction.extend({ }); Credit.reopenClass({ - serializer: Rev1Serializer.extend({ + serializer: TransactionSerializer.extend({ serialize: function(record) { var json = this._super(record); @@ -83,11 +83,6 @@ Credit.reopenClass({ } } - if (!Ember.isBlank(json.order_uri)) { - json.order = json.order_uri; - delete json.order_uri; - } - return json; } }).create(), diff --git a/app/models/customer.js b/app/models/customer.js index 4db5499fe..3572f29cb 100644 --- a/app/models/customer.js +++ b/app/models/customer.js @@ -1,5 +1,6 @@ import { CountryCodesToNames } from "balanced-dashboard/lib/country-codes"; import Model from "./core/model"; +import Order from "./order"; import Computed from "balanced-dashboard/utils/computed"; import FundingInstrumentsResultsLoader from "./results-loaders/funding-instruments"; import TransactionsResultsLoader from "./results-loaders/transactions"; @@ -83,6 +84,14 @@ var Customer = Model.extend({ return AccountsResultsLoader.create(attributes); }, + createOrder: function(description) { + var order = Order.create({ + description: description + }); + order.set("uri", this.get("orders_uri")); + return order.save(); + }, + type: function() { return (this.get('ein') || this.get('business_name')) ? CUSTOMER_TYPES.BUSINESS : CUSTOMER_TYPES.PERSON; }.property('ein', 'business_name'), diff --git a/app/models/debit.js b/app/models/debit.js index 5b267940f..6a71abd5d 100644 --- a/app/models/debit.js +++ b/app/models/debit.js @@ -2,6 +2,7 @@ import Computed from "balanced-dashboard/utils/computed"; import Transaction from "./transaction"; import Model from "./core/model"; import Utils from "balanced-dashboard/lib/utils"; +import TransactionSerializer from "../serializers/transaction"; var Debit = Transaction.extend({ @@ -59,4 +60,8 @@ var Debit = Transaction.extend({ }.property('amount', 'refund_amount', 'is_succeeded', 'dispute') }); +Debit.reopenClass({ + serializer: TransactionSerializer.create() +}); + export default Debit; diff --git a/app/models/factories/debit-card-transaction-factory.js b/app/models/factories/debit-card-transaction-factory.js index a5a9981af..1e0358576 100644 --- a/app/models/factories/debit-card-transaction-factory.js +++ b/app/models/factories/debit-card-transaction-factory.js @@ -1,5 +1,6 @@ import Debit from "../debit"; import Card from "../card"; +import Customer from "../customer"; import TransactionFactory from "./transaction-factory"; import ValidationHelpers from "balanced-dashboard/utils/validation-helpers"; @@ -13,7 +14,7 @@ var DebitCardTransactionFactory = TransactionFactory.extend({ }, getDebitAttributes: function() { - return this.getProperties("amount", "appears_on_statement_as", "description"); + return this.getProperties("amount", "appears_on_statement_as", "debit_description"); }, validations: { @@ -32,22 +33,51 @@ var DebitCardTransactionFactory = TransactionFactory.extend({ var baseDebitAttributes = this.getDebitAttributes(); var self = this; this.validate(); + if (this.get("isValid")) { - Card.create(this.getDestinationAttributes()) - .tokenizeAndCreate() - .then(function(card) { + var buyer = Customer.create({ + name: self.get("buyer_name"), + email: self.get("buyer_email_address") + }); + var card; + + buyer.save() + .then(function() { + return Card + .create(self.getDestinationAttributes()) + .tokenizeAndCreate(buyer.get("uri")); + }) + .then(function(c) { + card = c; + var seller = Customer.create({ + name: self.get("seller_name"), + email: self.get("seller_email_address") + }); + return seller.save(); + }) + .then(function(seller) { + var description = self.get("order_description"); + return seller.createOrder(description); + }) + .then(function(order) { var debitAttributes = _.extend({}, baseDebitAttributes, { + customer_uri: buyer.get("uri"), uri: card.get('debits_uri'), - source_uri: card.get('uri') + source_uri: card.get('uri'), + order_uri: order.get("uri") }); return Debit.create(debitAttributes).save(); }) .then(function(model) { deferred.resolve(model); }, function(response) { - response.errors.forEach(function(error) { - self.get("validationErrors").add(undefined, "server", null, error.description); - }); + if (response.message) { + self.get("validationErrors").add(undefined, "server", null, response.message); + } else if (response.errors) { + response.errors.forEach(function(error) { + self.get("validationErrors").add(undefined, "server", null, error.description); + }); + } deferred.reject(self); }); } else { diff --git a/app/serializers/transaction.js b/app/serializers/transaction.js new file mode 100644 index 000000000..7bddbaa0b --- /dev/null +++ b/app/serializers/transaction.js @@ -0,0 +1,18 @@ +import Rev1Serializer from "./rev1"; + +var TransactionSerializer = Rev1Serializer.extend({ + _propertiesMap: function(record) { + var json = this._super(record); + + if (!Ember.isBlank(json.order_uri)) { + json.order = json.order_uri; + delete json.order_uri; + } + + console.log(json); + return json; + } +}) + + +export default TransactionSerializer; diff --git a/app/templates/modals/card-debit-create-modal.hbs b/app/templates/modals/card-debit-create-modal.hbs index fb7b2ddce..69656faac 100644 --- a/app/templates/modals/card-debit-create-modal.hbs +++ b/app/templates/modals/card-debit-create-modal.hbs @@ -1,4 +1,13 @@ -{{#view "form-fields/form-section" appearsOnStatementAsLabelText=view.appearsOnStatementAsLabelText appearsOnStatementAsMaxLength=view.appearsOnStatementAsMaxLength model=view.model sectionTitle="Payment information"}} +{{#view "form-fields/form-section" sectionTitle="Order information" appearsOnStatementAsLabelText=view.appearsOnStatementAsLabelText appearsOnStatementAsMaxLength=view.appearsOnStatementAsMaxLength model=view.model}} + {{view "form-fields/text-form-field" model=view.model field="order_description" labelText="Order description" inputClassNames="full"}} + + {{view "form-fields/text-form-field" model=view.model field="seller_name" labelText="Merchant's name" inputClassNames="full"}} + {{view "form-fields/email-form-field" model=view.model field="seller_email_address" labelText="Merchant's email address" inputClassNames="full"}} +{{/view}} + +{{#view "form-fields/form-section" sectionTitle="Buyer information" model=view.model}} + {{view "form-fields/text-form-field" model=view.model field="buyer_name" labelText="Name" inputClassNames="full"}} + {{view "form-fields/email-form-field" model=view.model field="buyer_email_address" labelText="Email address" inputClassNames="full"}} {{view "form-fields/text-form-field" model=view.model field="name" labelText="Card holder's name" inputClassNames="full"}} {{view "form-fields/text-form-field" model=view.model field="number" labelText="Card number" inputClassNames="full"}} {{view "form-fields/text-form-field" model=view.model field="cvv" labelText="Security code" tooltipTitle="Where is the security code?" tooltipContent='Credit Card Instructions'}} @@ -9,12 +18,13 @@ labelText="Expiration date" name="expiration_date" }} - {{view "form-fields/text-form-field" model=view.model field="postal_code" labelText="Billing zip code" explanationText="Required for American Express cards"}} +{{/view}} +{{#view "form-fields/form-section" sectionTitle="Debit information" appearsOnStatementAsLabelText=view.appearsOnStatementAsLabelText appearsOnStatementAsMaxLength=view.appearsOnStatementAsMaxLength model=view.model}} {{view "form-fields/amount-form-field" model=view.model field="dollar_amount" labelText="Amount"}} {{view "form-fields/text-form-field" model=view.model field="appears_on_statement_as" labelText=view.appearsOnStatementAsLabelText maxlength=view.appearsOnStatementAsMaxLength inputClassNames="full"}} - {{view "form-fields/text-form-field" model=view.model field="description" labelText="Internal description" inputClassNames="full"}} + {{view "form-fields/text-form-field" model=view.model field="debit_description" labelText="Debit description" inputClassNames="full"}} {{/view}} diff --git a/app/views/form-fields/email-form-field.js b/app/views/form-fields/email-form-field.js new file mode 100644 index 000000000..fb532950c --- /dev/null +++ b/app/views/form-fields/email-form-field.js @@ -0,0 +1,8 @@ +import BaseFormFieldView from "./base-form-field"; + +var EmailFormFieldView = BaseFormFieldView.extend({ + inputType: "email", + inputClassNames: "full" +}); + +export default EmailFormFieldView; diff --git a/app/views/modals/card-debit-create-modal.js b/app/views/modals/card-debit-create-modal.js index 495f9ade6..339c3f8d8 100644 --- a/app/views/modals/card-debit-create-modal.js +++ b/app/views/modals/card-debit-create-modal.js @@ -7,9 +7,9 @@ import Save from "balanced-dashboard/views/modals/mixins/object-action-mixin"; var CardDebitCreateModalView = ModalBaseView.extend(Save, Full, Form, { templateName: "modals/card-debit-create-modal", elementId: "charge-card", - title: "Debit a card", + title: "Create an order", cancelButtonText: "Cancel", - submitButtonText: "Debit", + submitButtonText: "Create", model: function() { var DebitCardTransactionFactory = require("balanced-dashboard/models/factories/debit-card-transaction-factory")['default'];