Skip to content

Commit

Permalink
Create "Tax Detail" view in Orders Dashboard (#2005)
Browse files Browse the repository at this point in the history
* Update version number

* new meta key in registry, allow package registry items to override default meta title

* lint fixes

* Rewrite example payment settings pane to react #1817 (#1848)

* Have base to be release20

* Nitpick change on index

* Convert social settings to React with new cards (#1854)

* Convert social settings to React with new cards

* Save card open state

* Add new SettingsCard component

 - SettingsCard component wraps many components necessary for a
dashboard settings card.
- Added method for updating user preferences

* Added a custom React semi-auto Form component

To help standardize all settings cards a new `Form` component has been
added that can use `SimpleSchema` to generate a basic, single level
form with validation.

* Update social settings and form component

- Add success message on submit
- Remove unused code
- Fix glitch with auto form and error messages

* Added prop type for switchName

* Show Sidebar shipping in checkout

* Set actionView after payment checkout step

* 1907 PDP template switcher (#1909)

* Add the ability to switch PDP template

Adds a select box to the PDP Admin view which allows a user to switch
between different registered templates.

* Add a templateFor array for tagging templates for specific views

* Removed console log

* Update select with i18n

* Hide sidebar on entry to profile page

* Add presentational aspect for invoice

* Add presentational view for invoice

* Added switch component to list item (#1936)

* Added switch component to list item

* Remove unused prop

* Remove broken check for bulk write support (#1929)

* Remove broken check for bulk write support

* Check that batch is not empty before trying to execute it

* validated reaction json (#1937)

* State feedback capture payment 1243 (#1926)

* Add a spinner to capture payment button

* Add conditional display of spinner

* Add loading state onto capture payment button

* Add loading state for refunds

* Disable the buttons when spinner is displayed/ when loading

* Remove unnecessary import

* Add loading state while waiting for refunds

* remove react-bootstrap (#1914)

* remove unused email setting dashboard tab

* camelCase filenames

* pull

* remove unused templates

* remove unneeded limit function (griddle includes this)

* remove no longer needed functionality

* update email publication

* remove react-bootstrap

* i18n updates

* add new sizes to actionView via registry

* customize griddle columns for data display

* remove react-bootstrap

* switch TextField to Reaction version

* pass correct props to select field

* move i18n into package

* ALL CAPS

* remove FieldGroup component

* remove fieldGroup component

* remove fieldGroup component

* remove react-bootstrap

* Add state to the invoice view

* Detail on invoices captured

* Add roll over list capability

* Add single invoice render

* Add roll down list not quantity based

* Update product handle when title changes (#1898)

* Update product handle when title changes

Ensure the handle is always set to the slugified product title, custom
input from user, the product id.

* Remove log statement

* Redirect on handle change

* Fix product grid link to use published product handle, not revision

* Better handling for validation errors

- Catch collection error
- Force update component with validation error so blank fields like
product title, will get the original title put back to keep it from
being blank

* Update logic for product handle update

* Add presentational aspect for invoice

* Add presentational view for invoice

* Add state to the invoice view

* Detail on invoices captured

* Add roll over list capability

* Add single invoice render

* Add roll down list not quantity based

* Display unique items only

* Add quantities to line items

* Remove unnecessary parts of the view

* Fix search isSoldOut issue (#1904)

* allow denormalization of certain fields outside of revision control

* allow denormalization of certain fields outside of revision control

* Seperate components for roll up lists and line items

* Add cancel capability

* Clean up UI

* Add item functions

* Fix Sidebar Context (#1932)

* Show Sidebar shipping in checkout

* Set actionView after payment checkout step

* Hide sidebar on entry to profile page

* Remove Inventory subscription that is not in use (#1951)

* Get package data by shopId as well as package name (#1949)

* Add capture payments capability

* Add refunds fields

* Seperate concerns in invoice component

* Clean up invoice code

* Refactorline items

* Updated i18n settings panel (#1947)

* Updated i18n settings panel

- added new package for i18n settings
- converted to react
- added currency list
- added ability to save open state to SettingsCard to user preferences
- added ability to pluck fields in form component to enable concise
forms

* Update currency lists in admin

- Only show enabled currencies in dropdown
- Do not sure updatedAt field

* Added ability to toggle all on or all off for languages and currencies

* Removed unused code

* Updated colors for card toolbar

* fix props to show correct attribute

* fixes z-index issue on select container

* fix language props

* fix prop to show enabled languages only

* Avalara Tax Compliance (#1870)

* Save company object from Avalara API

* Load `appVersion` from package,json at startup. Create global `getAppVersion`

* create avaGet function to pass in extra header info. Add getTaxCodes function

* Extend plugin to also provide tax codes

* Add Test connection option in Avalara admin dashboard

* Send taxCode along with cart/orders

* Capture full tax detail in "taxes" field

* Update Test Credentials to use companyCode API

* Add input field for shipping tax code

* Add provides: taxCodes API to taxcloud

* add itemCode to cart/order payload

* use item id as line number. Pass in correct productId

* Pass in shipping as additional non-taxable (based on taxcode) item

* allow avaPost/avaGet to be used asynchronously

* Add setting to turn off tax calculation separately from disabling the module

* Add the rest of the fields to the form (except validation countries)

* Use correct UID and correct URL for getTaxCode

* Add setup for address validation by country

* Don't commit documents when commit is turned off. Eliminate unneeded functions

* Eliminate async versions of avaGet/avaPost. These should never be called by external module

* Add defaults for new configuration settings. Make shippingTaxCode required

* Make get/post methods use timeout, do some logging.

* Don't do address validation when package is disabled, even when addressvalidation is enabled

* Enable addressValidation by default

* Enable addressValidation by default

* Fix date parameter

* Merge. Fix conflicts.

* Modify auth arg for test credentials setup

* Extend timeout during test credentials call

* Limit address validation country options to US and CA

* Fix returned object for non-validated addresses

* Log Avalara details to custom Avalogger

* Set new defaults

* Add tax settings to account profile page

* Update account find for taxsettings to subscribe

* Only log if logging is enabled

* Write out Avalara requests to Logs collection via Bunyan logger

* Add log retention duration setting

* Add jobs to cleanup logs older than configured setting

* Add logs subscription that totally doesn't work

* Add logs publication

* Get logs and pass into Template

* Add Log-specific wrapper for Griddle

* Show individual log records in detail form

* Refine grid and detail results

* Populate entity codes and plug into taxCalc

* Use new field names confirmed by AvaTax

* Add taxSettings to recordOrder

* Update entity code field key

* removed excess panel wrapper around griddle table

* Add translations

* Show tax settings only if avalara enabled

* Fix import order.

* Setup error handling on Avalara methods

* Add dimensions/tax code to PDP (#1931)

* Edit product's schema file to include product dimensions

* Add product dimensions in variant form

* Edit product's schema and product admin form to include country of origin

* Edit product's schema and product admin form to include tax description

* Edit product's schema and product variant form to include origin country (yet to pre-populate from product's origin country)

* Edit variant form to include list of tax codes

* Refactor listTaxCodes method

* Refactor listTaxCodes method to use template state instead of sessions

* Refactor listTaxCodes method to use template state instead of sessions - template state now works

* Edit taxCodes schema to include more descriptive fields

* Include server method to save tax codes to TaxCodes collection

* (First attempt) saving taxcodes to database

* Successfully fetching taxcodes from database

* Add error block in fetching from db method

* change value of taxcode being saved in product details

* Adding select2 package

* Using select2 to display tax codes in nicer looking select box

* Correcting import order

* Editing required fields in product schema

* Using plain select field to display tax codes

* Remove tax code label; add select2 call in onRendered function instead of onCreated

* Displaying default tax code as selected in select box

* Removing unused meteor package; correcting import order

* Throwing more descriptive meteor error on insertTaxCodes method

* Display simple input box if tax provider is not enabled

* Correct the way we test for validation on address2

* Remove extra panel divs

* Add account ID to account management screen

* Adjust log details for when there is no document type

* Rename files to match style guide

* Use individual taxSettings form each account

* Add check to prevent populating duplicates

* Fix reference to accountschema

* Fix form update to corresponding accounts

* Add unique tax setting by customer to Avalara payload

* Fix exception error on geoCoder call

* Only pass in regions when it's a "country with regions"

* Revert "Only pass in regions when it's a "country with regions""

This reverts commit b809085.

* Create a refundReference which is cartId + date

* Ignore line items are not marked taxable

* Move taxDescription down to the variant level and pass if exists

* Move tax settings form into manage sidebar

* Fix tax settings saving bug

* Renamed files to fit style guide

* Don't allow a wide-open Account publication

* Remove unnecessary subscription

* Don't call API if entity codes is already populated

* Simplify logic for returning no results

* Don't select a tax rate but a tax code

* Rename function

* Properly set Avalara countryList defaultValues

* Eliminate extra slash

* Eliminate all extra slashes

* Check to ensure data is returned from API

* Also log errors in Avalogger. Correctly filter for taxable items.

* Require shopId

* linting fixes

* Add label to plain select. Rename method

* JSDoc linting

* Remove unused import

* Remove unused import

* Linting

* Check configuration and throw meaningful errors if not configured properly

* Add level to log so we can filter for errors

* Tweak HTML and styling in settings panel

* Fix i18n and timeout on testCredential

* Log error with error log level

* Moving select2 under community packages

* Adding error checks to taxcodes method

* Skip config check when testing credentials

* Trigger form validation before testcredentials

* Use native methods for assign and each

* Handle error on populating Avalara entity codes

* Add i18n for custom label

* Move i18n entry to appropriate module

* Move exemption settings into avalara module

* Implement i18n for missing fields in PDP

* Fix CircleCI failed tests

* Fix CircleCI failed tests

* Revert "Fix CircleCI failed tests"

This reverts commit 3b238a8.

* Revert "Fix CircleCI failed tests"

This reverts commit 66f0f78.

* Removing empty selector per CR

* Use import rather than fs to get package.json

* Change per CR

* Restructure Class syntax per CR

* Put back "Custom Packages" header

* Add TODO

* Changing default timeout to 3000 ms

* Correct error name and make error message more specific

* - updated Accounts publication name

- Update Accounts.single to UserAccount

* Fix: Dashboard panel keeps re-opening during checkout (#1956)

* Show sidebar only if shipping is not configured

* Refactor: Show sidebar only if shipping is not configured

* Fix to show sidebar only if payment is not configured

* localize prices in emails (#1957)

* add GetShopCurrency helper

* update cart currency when user changes currency

* update schema to include currency in cart / order

* add userCurrency and exchangeRate to carts orders

* update email templates to display formatted price

* update user emails to use user currency

* Use select box of countries rather than text field for "Origin Country" (#1967)

* Fix 404 when adding handle and then editing a variant before publishing.

* Fixed misspelling in comment

* Remove z-index from dropdown as it creates more issues than it solves

* Moved ColumnData component to its own file. (#1972)

* Prevent hiding of nested tags on mobile (#1971)

* Show Sidebar shipping in checkout

* Set actionView after payment checkout step

* Add presentational aspect for invoice

* Add presentational aspect for invoice

* Add presentational view for invoice

* Add presentational view for invoice

* Add state to the invoice view

* Add state to the invoice view

* Detail on invoices captured

* Detail on invoices captured

* Add roll over list capability

* Add roll over list capability

* Add single invoice render

* Add single invoice render

* Add roll down list not quantity based

* Display unique items only

* Add quantities to line items

* Remove unnecessary parts of the view

* Seperate components for roll up lists and line items

* Add cancel capability

* Clean up UI

* Add item functions

* Add capture payments capability

* Add refunds fields

* Seperate concerns in invoice component

* Clean up invoice code

* Refactorline items

* Add data into individual line items

* linting and minor error fixes (#1973)

* remove extra unneeded check for userId

This was causing the Logger error we were seeing

* update import order

* change way of calling userId

* fixed Shops.findOne

* updated variable name

* removed html error code from meteor error

* cart.billing should now be defined to include currency

* setting default currency if shop.currency is unavailable

* update client to match server

* lint fixes

* Avalara error handling (#1968)

* Taxcloud doesn't really support getTaxCodes yet

* Ok, calm down

* Taxcloud doesn't really provide taxCodes yet

* Log Tax code errors to Logs collection rather than throwing a Meteor.Error

* Add missing import

* Use name from namespaced provides rather than name

* Pulling tax codes from TaxCloud

* Configure saving taxcloud taxes to db and displaying them

* Move around UI components

* Move around UI components

* Add total price of line items

* Format pricing to have dollar signs

* Finalize on tax data

* Iterate on design

* Review tax display

* Can drag drop images onto order

* Only display Add discount when discounts are enabled

* Correct syntax issues after review

* Tweak syntax of functions
  • Loading branch information
joykare authored and brent-hoover committed Mar 21, 2017
1 parent 261cb13 commit 261a351
Show file tree
Hide file tree
Showing 15 changed files with 790 additions and 176 deletions.
1 change: 1 addition & 0 deletions imports/plugins/core/checkout/client/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import "./templates/cartPanel/cartPanel.html";
import "./templates/cartPanel/cartPanel.js";

import "./templates/checkout/addressBook/addressBook.html";
import "./templates/checkout/addressBook/addressBook.js";
import "./templates/checkout/completed/completed.html";
import "./templates/checkout/completed/completed.js";
import "./templates/checkout/header/header.html";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Template } from "meteor/templating";
import { Reaction } from "/client/api";

Template.checkoutAddressBook.onCreated(function () {
Reaction.showActionView({
provides: "settings",
name: "settings/shipping",
template: "shippingSettings"
});
});
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import "./review.html";
import { Meteor } from "meteor/meteor";
import { Template } from "meteor/templating";
import { Reaction } from "/client/api";

/**
* review status
Expand All @@ -9,4 +10,9 @@ import { Template } from "meteor/templating";

Template.checkoutReview.onRendered(function () {
Meteor.call("workflow/pushCartWorkflow", "coreCartWorkflow", "checkoutReview");
Reaction.showActionView({
name: "payment/settings",
provides: "settings",
template: "paymentSettings"
});
});
5 changes: 3 additions & 2 deletions imports/plugins/core/discounts/client/components/form.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export default class DiscountForm extends Component {
this.state = {
discount: this.props.discount,
validationMessage: null,
validatedInput: false,
validatedInput: this.props.validatedInput || false,
attempts: 0,
discountApplied: false
};
Expand Down Expand Up @@ -144,5 +144,6 @@ export default class DiscountForm extends Component {
DiscountForm.propTypes = {
collection: PropTypes.string,
discount: PropTypes.string,
id: PropTypes.string
id: PropTypes.string,
validatedInput: PropTypes.bool
};
6 changes: 4 additions & 2 deletions imports/plugins/core/discounts/client/components/list.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class DiscountList extends Component {
// load form input view
renderNoneFound() {
return (
<DiscountForm id={this.props.id} collection={this.props.collection}/>
<DiscountForm id={this.props.id} collection={this.props.collection} validatedInput={this.props.validatedInput} />
);
}

Expand All @@ -63,7 +63,8 @@ class DiscountList extends Component {
DiscountList.propTypes = {
collection: PropTypes.string,
id: PropTypes.string,
listItems: PropTypes.array
listItems: PropTypes.array,
validatedInput: PropTypes.bool
};

function composer(props, onData) {
Expand All @@ -84,6 +85,7 @@ function composer(props, onData) {

onData(null, {
collection: props.collection,
validatedInput: props.validatedInput,
id: props.id,
listItems: listItems
});
Expand Down
152 changes: 152 additions & 0 deletions imports/plugins/core/orders/client/components/invoice.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
import React, { Component, PropTypes } from "react";
import { formatPriceString } from "/client/api";
import { Translation } from "/imports/plugins/core/ui/client/components";
import DiscountList from "/imports/plugins/core/discounts/client/components/list";

class Invoice extends Component {
static propTypes = {
canMakeAdjustments: PropTypes.bool,
collection: PropTypes.string,
dateFormat: PropTypes.func,
discounts: PropTypes.bool,
handleClick: PropTypes.func,
invoice: PropTypes.object,
isFetching: PropTypes.bool,
isOpen: PropTypes.bool,
orderId: PropTypes.string,
paymentCaptured: PropTypes.bool,
refunds: PropTypes.array
}

renderDiscountForm() {
const { isOpen, orderId, collection } = this.props;

return (
<div>
{isOpen &&
<div>
<hr/>
<DiscountList
id={orderId}
collection={collection}
validatedInput={true}
/>
<hr/>
</div>
}
</div>
);
}

renderRefundsInfo() {
const { isFetching, refunds, dateFormat } = this.props;

return (
<div>
{isFetching &&
<div className="form-group order-summary-form-group">
<strong>Loading Refunds</strong>
<div className="invoice-details">
<i className="fa fa-spinner fa-spin" />
</div>
</div>
}

{refunds && refunds.map((refund) => (
<div className="order-summary-form-group text-danger" key={refund.created} style={{ marginBottom: 15 }}>
<strong>Refunded on: {dateFormat(refund.created, "MM/D/YYYY")}</strong>
<div className="invoice-details"><strong>{formatPriceString(refund.amount)}</strong></div>
</div>
))}
</div>
);
}

renderTotal() {
const { invoice } = this.props;

return (
<div className="order-summary-form-group">
<hr/>
<strong>TOTAL</strong>
<div className="invoice-details">
<strong>{formatPriceString(invoice.total)}</strong>
</div>
</div>
);
}

renderConditionalDisplay() {
const { canMakeAdjustments, paymentCaptured } = this.props;

return (
<div>
{canMakeAdjustments ?
<div> {this.renderTotal()} </div> :
<span>
{paymentCaptured ?
<div>
{this.renderRefundsInfo()}
</div>
:
<div> {this.renderTotal()} </div>
}
</span>
}
</div>
);
}

render() {
const { invoice, discounts, handleClick } = this.props;

return (
<div>
<div className="order-summary-form-group">
<strong>Quantity Total</strong>
<div className="invoice-details">
{invoice.totalItems}
</div>
</div>

<div className="order-summary-form-group">
<strong><Translation defaultValue="Subtotal" i18nKey="cartSubTotals.subtotal"/></strong>
<div className="invoice-details">
{formatPriceString(invoice.subtotal)}
</div>
</div>

<div className="order-summary-form-group">
<strong><Translation defaultValue="Shipping" i18nKey="cartSubTotals.shipping"/></strong>
<div className="invoice-details">
{formatPriceString(invoice.shipping)}
</div>
</div>

<div className="order-summary-form-group">
<strong><Translation defaultValue="Tax" i18nKey="cartSubTotals.tax"/></strong>
<div className="invoice-details">
{formatPriceString(invoice.taxes)}
</div>
</div>

{discounts &&
<div>
<div className="order-summary-form-group">
<strong><Translation defaultValue="Discount" i18nKey="cartSubTotals.discount"/></strong>
<div className="invoice-details">
<i className="fa fa-tag fa-lg" style={{ marginRight: 2 }}/>
<a className="btn-link" onClick={handleClick}>Add Discount</a>
</div>
</div>
{this.renderDiscountForm()}
</div>
}
{this.renderConditionalDisplay()}
</div>
);
}
}

export default Invoice;

150 changes: 150 additions & 0 deletions imports/plugins/core/orders/client/components/lineItems.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
import React, { Component, PropTypes } from "react";
import { formatPriceString } from "/client/api";
import { Translation } from "/imports/plugins/core/ui/client/components";

class LineItems extends Component {
static propTypes = {
displayMedia: PropTypes.func,
handleClick: PropTypes.func,
isExpanded: PropTypes.func,
onClose: PropTypes.func,
uniqueItems: PropTypes.array
}

calculateTotal(price, shipping, taxes) {
return formatPriceString(price + shipping + taxes);
}

renderLineItem(uniqueItem, quantity) {
const { handleClick, displayMedia } = this.props;

return (
<div className="order-items">
<div
className="invoice order-item form-group order-summary-form-group"
onClick={() => handleClick(uniqueItem.cartItemId)}
style={{ height: 70 }}
>

<div className="order-item-media" style={{ marginLeft: 15 }}>
{ !displayMedia(uniqueItem) ?
<img src= "/resources/placeholder.gif" /> :
<img
src={displayMedia(uniqueItem).url()}
/>
}
</div>

<div className="order-item-details">
<div className="order-detail-title">
{uniqueItem.title} <br/><small>{uniqueItem.variants.title}</small>
</div>
</div>

<div className="order-detail-quantity">
{quantity || 1}
</div>

<div className="order-detail-price">
<div className="invoice-details" style={{ marginRight: 15 }}>
<strong>{formatPriceString(uniqueItem.variants.price)}</strong>
</div>
</div>

</div>
</div>
);
}

renderLineItemInvoice(uniqueItem, shippingRate, quantity) {
return (
<div>
<div className="order-summary-form-group">
<strong><Translation defaultValue="Subtotal" i18nKey="cartSubTotals.subtotal"/></strong>
<div className="invoice-details">
{formatPriceString(uniqueItem.variants.price)}
</div>
</div>

<div className="order-summary-form-group">
<strong><Translation defaultValue="Shipping" i18nKey="cartSubTotals.shipping"/></strong>
<div className="invoice-details">
{formatPriceString(shippingRate)}
</div>
</div>

<div className="order-summary-form-group">
<strong>Item tax</strong>
<div className="invoice-details">
{uniqueItem.taxDetail ? formatPriceString(uniqueItem.taxDetail.tax / quantity) : formatPriceString(0)}
</div>
</div>

<div className="order-summary-form-group">
<strong>Tax code</strong>
<div className="invoice-details">
{uniqueItem.taxDetail ? uniqueItem.taxDetail.taxCode : uniqueItem.variants.taxCode}
</div>
</div>

<div className="order-summary-form-group">
<strong>TOTAL</strong>
<div className="invoice-details">
{uniqueItem.taxDetail ?
<strong>
{this.calculateTotal(uniqueItem.variants.price, shippingRate, uniqueItem.taxDetail.tax)}
</strong> :
<strong>
{this.calculateTotal(uniqueItem.variants.price, shippingRate, 0)}
</strong>
}
</div>
</div>
<br/>
</div>
);
}

render() {
const { uniqueItems, isExpanded, onClose } = this.props;

return (
<div>
{uniqueItems.map((uniqueItem) => {
if (!isExpanded(uniqueItem.cartItemId)) {
return (
<div key={uniqueItem.cartItemId}> { this.renderLineItem(uniqueItem.items[0], uniqueItem.items.length) } </div>
);
}

return (
<div className="roll-up-invoice-list" key={uniqueItem.cartItemId}>
<div className="roll-up-content">

<div style={{ float: "right" }}>
<button className="rui btn btn-default flat icon-only" onClick={() => onClose(uniqueItem.cartItemId)}>
<i
className="rui font-icon fa-lg fa fa-times"
/>
</button>
</div>

<br/><br/>

{uniqueItem.items.map((item) => (
<div key={item._id}>
{ this.renderLineItem(item) }
{ this.renderLineItemInvoice(item, uniqueItem.shippingRate, uniqueItem.items.length) }
</div>
))}

</div>
</div>
);
})}
</div>
);
}
}

export default LineItems;
Loading

0 comments on commit 261a351

Please sign in to comment.