Refunds (#870)
* 1721 - add refunds miscellaneous view (#860) * Create new page for Miscellaneous Refunds * Replace refund order dialog with dedicated page * Add data test ids * Update order details view for refunds (#874) * 1719 - add refund entry to order history (#875) * Add refund order history entry * Update refund event with the right query * 1722 - add refunds product view (#873) * Create new page for Miscellaneous Refunds * Replace refund order dialog with dedicated page * Add data test ids * Create refund products table * Implement refund products view * Update refund mutation with product lines input * Fix products quantities on refund page * Fix order refund submission * Fix products refund submission input variables * Filter out fulfillments on refund page * Update refund page in storybook * Fix test snapshots after wrong refunds rebase * Set max refund as captured amount * Refund queries adjustments * Display refund values with nullish coalescing operator * Update test snapshots with refunds * Refactor order refund values calculation * Create and use refund order line fragment * Use old simple refund mutation for miscellaneous refund * Submit for refund only lines with non-zero quantity set * Fix showing refund error * Fix refund details on order details page (#879) * Update order details view for refunds (#874) * 1719 - add refund entry to order history (#875) * Add refund order history entry * Update refund event with the right query * 1722 - add refunds product view (#873) * Create new page for Miscellaneous Refunds * Replace refund order dialog with dedicated page * Add data test ids * Create refund products table * Implement refund products view * Update refund mutation with product lines input * Fix products quantities on refund page * Fix order refund submission * Fix products refund submission input variables * Filter out fulfillments on refund page * Update refund page in storybook * Fix test snapshots after wrong refunds rebase * Set max refund as captured amount * Refund queries adjustments * Display refund values with nullish coalescing operator * Update test snapshots with refunds * Refactor order refund values calculation * Create and use refund order line fragment * Use old simple refund mutation for miscellaneous refund * Submit for refund only lines with non-zero quantity set * Fix showing refund error * Add missing refund amount to order history * Merge repeated order lines in fulfillment lines * Update order history events types and test snapshots * Update changelog with refunds changes
This commit is contained in:
parent
b16206dfa8
commit
eb351b396a
72 changed files with 8350 additions and 296 deletions
|
@ -7,6 +7,7 @@ All notable, unreleased changes to this project will be documented in this file.
|
|||
- Add Order Confirmation settings - #840 by @orzechdev and @mmarkusik
|
||||
- Add Page Types - #807 by @orzechdev
|
||||
- Add shipping methods to translation section - #864 by @marekchoinski
|
||||
- New Miscellaneous and Product refunds - #870 by @orzechdev
|
||||
|
||||
# 2.11.1
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ module.exports = api => {
|
|||
}
|
||||
],
|
||||
"@babel/plugin-proposal-object-rest-spread",
|
||||
"@babel/plugin-proposal-nullish-coalescing-operator",
|
||||
"react-intl-auto"
|
||||
];
|
||||
|
||||
|
|
|
@ -3284,6 +3284,10 @@
|
|||
"context": "fulfillment group tracking number",
|
||||
"string": "Edit tracking"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderFulfillment_dot_2567258278": {
|
||||
"context": "refunded fulfillment, section header",
|
||||
"string": "Refunded ({quantity})"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderFulfillment_dot_2796503714": {
|
||||
"context": "ordered product quantity",
|
||||
"string": "Quantity"
|
||||
|
@ -3323,6 +3327,12 @@
|
|||
"context": "order history message",
|
||||
"string": "Order address was updated"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderHistory_dot_123236698": {
|
||||
"string": "Shipment was refunded"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderHistory_dot_1322321687": {
|
||||
"string": "Refunded amount"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderHistory_dot_1463685940": {
|
||||
"context": "order history message",
|
||||
"string": "Order was marked as paid"
|
||||
|
@ -3407,6 +3417,10 @@
|
|||
"context": "order history message",
|
||||
"string": "Products were added to draft order"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderHistory_dot_3731274949": {
|
||||
"context": "order history message",
|
||||
"string": "Order was refunded by {refundedBy}"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderHistory_dot_393045022": {
|
||||
"context": "order history message",
|
||||
"string": "Invoice no. {invoiceNumber} was updated"
|
||||
|
@ -3434,6 +3448,9 @@
|
|||
"context": "order history message",
|
||||
"string": "Payment failed"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderHistory_dot_492197448": {
|
||||
"string": "Products refunded"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderHistory_dot_493321552": {
|
||||
"context": "order history message",
|
||||
"string": "Order cancel information was sent to customer"
|
||||
|
@ -3546,10 +3563,6 @@
|
|||
"context": "dialog header",
|
||||
"string": "Capture Payment"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPaymentDialog_dot_250371749": {
|
||||
"context": "dialog header",
|
||||
"string": "Refund Payment"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPaymentDialog_dot_75546233": {
|
||||
"context": "amount of refunded money",
|
||||
"string": "Amount"
|
||||
|
@ -3561,6 +3574,10 @@
|
|||
"context": "dialog header",
|
||||
"string": "Void Payment"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_1322321687": {
|
||||
"context": "order payment",
|
||||
"string": "Refunded amount"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_1325966144": {
|
||||
"context": "order shipping method name",
|
||||
"string": "Shipping"
|
||||
|
@ -3633,6 +3650,162 @@
|
|||
"src_dot_orders_dot_components_dot_OrderProductAddDialog_dot_353369701": {
|
||||
"string": "No products matching given query"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderRefundAmountValues_dot_1580639738": {
|
||||
"context": "order refund amount",
|
||||
"string": "Proposed refund amount"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderRefundAmountValues_dot_1705174606": {
|
||||
"context": "order refund amount",
|
||||
"string": "Max Refund"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderRefundAmountValues_dot_1734445951": {
|
||||
"context": "order refund amount",
|
||||
"string": "Refund total amount"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderRefundAmountValues_dot_2045860028": {
|
||||
"context": "order refund amount",
|
||||
"string": "Authorized Amount"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderRefundAmountValues_dot_2854815744": {
|
||||
"context": "order refund amount",
|
||||
"string": "Previously refunded"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderRefundAmountValues_dot_2907874606": {
|
||||
"context": "order refund amount",
|
||||
"string": "Selected products value"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderRefundAmountValues_dot_79173946": {
|
||||
"context": "order refund amount",
|
||||
"string": "Shipment cost"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderRefundAmount_dot_120912052": {
|
||||
"context": "order refund amount",
|
||||
"string": "Refunded items can’t be fulfilled"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderRefundAmount_dot_159210811": {
|
||||
"string": "Amount must be bigger than 0"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderRefundAmount_dot_2256869831": {
|
||||
"context": "section header",
|
||||
"string": "Refunded Amount"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderRefundAmount_dot_2845258362": {
|
||||
"context": "order refund amount, input button",
|
||||
"string": "Refund"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderRefundAmount_dot_4033685232": {
|
||||
"string": "Amount cannot be bigger than max refund"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderRefundAmount_dot_40513382": {
|
||||
"context": "order refund amount, input button",
|
||||
"string": "Refund {currency} {amount}"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderRefundAmount_dot_4224226791": {
|
||||
"context": "label",
|
||||
"string": "Automatic Amount"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderRefundAmount_dot_508357513": {
|
||||
"context": "label",
|
||||
"string": "Manual Amount"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderRefundAmount_dot_553737700": {
|
||||
"context": "checkbox",
|
||||
"string": "Refund shipment costs"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderRefundAmount_dot_75546233": {
|
||||
"context": "order refund amount, input label",
|
||||
"string": "Amount"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderRefundFulfilledProducts_dot_1134347598": {
|
||||
"context": "tabel column header",
|
||||
"string": "Price"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderRefundFulfilledProducts_dot_1657559629": {
|
||||
"string": "No products found"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderRefundFulfilledProducts_dot_1895667608": {
|
||||
"context": "tabel column header",
|
||||
"string": "Product"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderRefundFulfilledProducts_dot_3536696555": {
|
||||
"context": "tabel column header",
|
||||
"string": "Refunded Qty"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderRefundFulfilledProducts_dot_3988345170": {
|
||||
"context": "button",
|
||||
"string": "Set maximal quantities"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderRefundFulfilledProducts_dot_615325604": {
|
||||
"context": "section header",
|
||||
"string": "Fulfillment"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderRefundFulfilledProducts_dot_878013594": {
|
||||
"context": "tabel column header",
|
||||
"string": "Total"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderRefundFulfilledProducts_dot_937914544": {
|
||||
"context": "error message",
|
||||
"string": "Improper value"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderRefundPage_dot_194531545": {
|
||||
"context": "page header",
|
||||
"string": "Order no. {orderNumber} - Refund"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderRefundPage_dot_3620521256": {
|
||||
"context": "page header",
|
||||
"string": "Order"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderRefundPage_dot_580490159": {
|
||||
"context": "page header with order number",
|
||||
"string": "Order #{orderNumber}"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderRefundUnfulfilledProducts_dot_1134347598": {
|
||||
"context": "tabel column header",
|
||||
"string": "Price"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderRefundUnfulfilledProducts_dot_1404351240": {
|
||||
"context": "section header",
|
||||
"string": "Unfulfilled Products"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderRefundUnfulfilledProducts_dot_1657559629": {
|
||||
"string": "No products found"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderRefundUnfulfilledProducts_dot_1895667608": {
|
||||
"context": "tabel column header",
|
||||
"string": "Product"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderRefundUnfulfilledProducts_dot_2271032876": {
|
||||
"context": "section notice",
|
||||
"string": "Unfulfilled products will be restocked"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderRefundUnfulfilledProducts_dot_3536696555": {
|
||||
"context": "tabel column header",
|
||||
"string": "Refunded Qty"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderRefundUnfulfilledProducts_dot_3988345170": {
|
||||
"context": "button",
|
||||
"string": "Set maximal quantities"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderRefundUnfulfilledProducts_dot_878013594": {
|
||||
"context": "tabel column header",
|
||||
"string": "Total"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderRefundUnfulfilledProducts_dot_937914544": {
|
||||
"context": "error message",
|
||||
"string": "Improper value"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderRefund_dot_1275363773": {
|
||||
"context": "section header",
|
||||
"string": "Refund Order"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderRefund_dot_refundMiscellaneous": {
|
||||
"context": "refund type",
|
||||
"string": "Miscellaneous Refund"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderRefund_dot_refundProducts": {
|
||||
"context": "refund type",
|
||||
"string": "Refund Products"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderSettingsPage_dot_1149215359": {
|
||||
"context": "header",
|
||||
"string": "Order settings"
|
||||
|
@ -3733,9 +3906,6 @@
|
|||
"src_dot_orders_dot_views_dot_OrderDetails_dot_617145655": {
|
||||
"string": "Shipping method successfully updated"
|
||||
},
|
||||
"src_dot_orders_dot_views_dot_OrderDetails_dot_667274681": {
|
||||
"string": "Payment successfully refunded"
|
||||
},
|
||||
"src_dot_orders_dot_views_dot_OrderDetails_dot_694622335": {
|
||||
"context": "window title",
|
||||
"string": "Draft Order #{orderNumber}"
|
||||
|
@ -3772,6 +3942,10 @@
|
|||
"src_dot_orders_dot_views_dot_OrderList_dot_1738939038": {
|
||||
"string": "Order draft successfully created"
|
||||
},
|
||||
"src_dot_orders_dot_views_dot_OrderRefund_dot_1366101924": {
|
||||
"context": "order refunded success message",
|
||||
"string": "Refunded Items"
|
||||
},
|
||||
"src_dot_pageTypes": {
|
||||
"context": "page types section name",
|
||||
"string": "Page Types"
|
||||
|
|
35
package-lock.json
generated
35
package-lock.json
generated
|
@ -946,6 +946,24 @@
|
|||
"@babel/plugin-syntax-json-strings": "^7.2.0"
|
||||
}
|
||||
},
|
||||
"@babel/plugin-proposal-nullish-coalescing-operator": {
|
||||
"version": "7.12.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.12.1.tgz",
|
||||
"integrity": "sha512-nZY0ESiaQDI1y96+jk6VxMOaL4LPo/QDHBqL+SF3/vl6dHkTwHlOI8L4ZwuRBHgakRBw5zsVylel7QPbbGuYgg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/helper-plugin-utils": "^7.10.4",
|
||||
"@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": {
|
||||
"version": "7.10.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
|
||||
"integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"@babel/plugin-proposal-numeric-separator": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.2.0.tgz",
|
||||
|
@ -1058,6 +1076,23 @@
|
|||
"@babel/helper-plugin-utils": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"@babel/plugin-syntax-nullish-coalescing-operator": {
|
||||
"version": "7.8.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
|
||||
"integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/helper-plugin-utils": "^7.8.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": {
|
||||
"version": "7.10.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
|
||||
"integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"@babel/plugin-syntax-numeric-separator": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.2.0.tgz",
|
||||
|
|
|
@ -81,6 +81,7 @@
|
|||
"@babel/core": "^7.7.7",
|
||||
"@babel/plugin-proposal-class-properties": "^7.5.0",
|
||||
"@babel/plugin-proposal-decorators": "^7.4.4",
|
||||
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.12.1",
|
||||
"@babel/plugin-proposal-numeric-separator": "^7.2.0",
|
||||
"@babel/plugin-proposal-object-rest-spread": "^7.5.4",
|
||||
"@babel/plugin-proposal-optional-chaining": "^7.8.3",
|
||||
|
|
|
@ -47,6 +47,7 @@ enum AccountErrorCode {
|
|||
DELETE_STAFF_ACCOUNT
|
||||
DELETE_SUPERUSER_ACCOUNT
|
||||
GRAPHQL_ERROR
|
||||
INACTIVE
|
||||
INVALID
|
||||
INVALID_PASSWORD
|
||||
LEFT_NOT_MANAGEABLE_PERMISSION
|
||||
|
@ -1999,8 +2000,16 @@ type FulfillmentLine implements Node {
|
|||
orderLine: OrderLine
|
||||
}
|
||||
|
||||
type FulfillmentRefundProducts {
|
||||
errors: [Error!]! @deprecated(reason: "Use typed errors with error codes. This field will be removed after 2020-07-31.")
|
||||
fulfillment: Fulfillment
|
||||
order: Order
|
||||
orderErrors: [OrderError!]!
|
||||
}
|
||||
|
||||
enum FulfillmentStatus {
|
||||
FULFILLED
|
||||
REFUNDED
|
||||
CANCELED
|
||||
}
|
||||
|
||||
|
@ -2648,6 +2657,7 @@ type Mutation {
|
|||
orderFulfill(input: OrderFulfillInput!, order: ID): OrderFulfill
|
||||
orderFulfillmentCancel(id: ID!, input: FulfillmentCancelInput!): FulfillmentCancel
|
||||
orderFulfillmentUpdateTracking(id: ID!, input: FulfillmentUpdateTrackingInput!): FulfillmentUpdateTracking
|
||||
orderFulfillmentRefundProducts(input: OrderRefundProductsInput!, order: ID!): FulfillmentRefundProducts
|
||||
orderMarkAsPaid(id: ID!, transactionReference: String): OrderMarkAsPaid
|
||||
orderRefund(amount: PositiveDecimal!, id: ID!): OrderRefund
|
||||
orderUpdate(id: ID!, input: OrderUpdateInput!): OrderUpdate
|
||||
|
@ -2846,6 +2856,7 @@ type Order implements Node & ObjectWithMetadata {
|
|||
totalBalance: Money!
|
||||
userEmail: String
|
||||
isShippingRequired: Boolean!
|
||||
linesAvailableForRefund: [OrderLineAvailableForRefund]!
|
||||
}
|
||||
|
||||
enum OrderAction {
|
||||
|
@ -2945,6 +2956,8 @@ enum OrderErrorCode {
|
|||
UNIQUE
|
||||
VOID_INACTIVE_PAYMENT
|
||||
ZERO_QUANTITY
|
||||
INVALID_REFUND_QUANTITY
|
||||
CANNOT_REFUND_FULFILLMENT_LINE
|
||||
INSUFFICIENT_STOCK
|
||||
DUPLICATED_INPUT_ITEM
|
||||
NOT_AVAILABLE_IN_CHANNEL
|
||||
|
@ -2971,6 +2984,7 @@ type OrderEvent implements Node {
|
|||
fulfilledItems: [FulfillmentLine]
|
||||
warehouse: Warehouse
|
||||
transactionReference: String
|
||||
shippingCostsIncluded: Boolean
|
||||
}
|
||||
|
||||
type OrderEventCountableConnection {
|
||||
|
@ -3028,6 +3042,7 @@ enum OrderEventsEnum {
|
|||
FULFILLMENT_CANCELED
|
||||
FULFILLMENT_RESTOCKED_ITEMS
|
||||
FULFILLMENT_FULFILLED_ITEMS
|
||||
FULFILLMENT_REFUNDED
|
||||
TRACKING_UPDATED
|
||||
NOTE_ADDED
|
||||
OTHER
|
||||
|
@ -3082,6 +3097,11 @@ type OrderLine implements Node {
|
|||
allocations: [Allocation!]
|
||||
}
|
||||
|
||||
type OrderLineAvailableForRefund {
|
||||
quantity: Int
|
||||
orderLine: OrderLine
|
||||
}
|
||||
|
||||
input OrderLineCreateInput {
|
||||
quantity: Int!
|
||||
variantId: ID!
|
||||
|
@ -3103,6 +3123,24 @@ type OrderRefund {
|
|||
orderErrors: [OrderError!]!
|
||||
}
|
||||
|
||||
input OrderRefundFulfillmentLineInput {
|
||||
fulfillmentLineId: ID
|
||||
quantity: Int!
|
||||
}
|
||||
|
||||
input OrderRefundLineInput {
|
||||
orderLineId: ID
|
||||
quantity: Int!
|
||||
}
|
||||
|
||||
input OrderRefundProductsInput {
|
||||
orderLines: [OrderRefundLineInput!]
|
||||
fulfillmentLines: [OrderRefundFulfillmentLineInput!]
|
||||
notifyCustomer: Boolean
|
||||
amountToRefund: PositiveDecimal
|
||||
includeShippingCosts: Boolean = false
|
||||
}
|
||||
|
||||
type OrderSettings {
|
||||
automaticallyConfirmAllNewOrders: Boolean!
|
||||
}
|
||||
|
@ -5089,6 +5127,7 @@ enum TransactionError {
|
|||
}
|
||||
|
||||
enum TransactionKind {
|
||||
EXTERNAL
|
||||
AUTH
|
||||
PENDING
|
||||
ACTION_TO_CONFIRM
|
||||
|
|
|
@ -39,6 +39,7 @@ interface PriceFieldProps {
|
|||
name?: string;
|
||||
value?: string | number;
|
||||
InputProps?: InputProps;
|
||||
inputProps?: InputProps["inputProps"];
|
||||
required?: boolean;
|
||||
onChange(event: any);
|
||||
}
|
||||
|
@ -55,7 +56,8 @@ export const PriceField: React.FC<PriceFieldProps> = props => {
|
|||
onChange,
|
||||
required,
|
||||
value,
|
||||
InputProps
|
||||
InputProps,
|
||||
inputProps
|
||||
} = props;
|
||||
|
||||
const classes = useStyles(props);
|
||||
|
@ -93,7 +95,8 @@ export const PriceField: React.FC<PriceFieldProps> = props => {
|
|||
}}
|
||||
inputProps={{
|
||||
min: minValue,
|
||||
type: "number"
|
||||
type: "number",
|
||||
...inputProps
|
||||
}}
|
||||
name={name}
|
||||
disabled={disabled}
|
||||
|
|
|
@ -15,9 +15,15 @@ const useStyles = makeStyles(
|
|||
formLabel: {
|
||||
marginBottom: theme.spacing(1)
|
||||
},
|
||||
radioGroupInline: {
|
||||
flexDirection: "row"
|
||||
},
|
||||
radioLabel: {
|
||||
marginBottom: -theme.spacing(0.5)
|
||||
},
|
||||
radioLabelInline: {
|
||||
marginRight: theme.spacing(4)
|
||||
},
|
||||
root: {
|
||||
"& $radioLabel": {
|
||||
"&:last-of-type": {
|
||||
|
@ -53,6 +59,7 @@ interface RadioGroupFieldProps {
|
|||
label?: React.ReactNode;
|
||||
name?: string;
|
||||
value: string | number;
|
||||
variant?: "block" | "inline";
|
||||
onChange: (event: React.ChangeEvent<any>) => void;
|
||||
}
|
||||
|
||||
|
@ -66,7 +73,8 @@ export const RadioGroupField: React.FC<RadioGroupFieldProps> = props => {
|
|||
value,
|
||||
onChange,
|
||||
name,
|
||||
hint
|
||||
hint,
|
||||
variant = "block"
|
||||
} = props;
|
||||
const classes = useStyles(props);
|
||||
|
||||
|
@ -86,13 +94,19 @@ export const RadioGroupField: React.FC<RadioGroupFieldProps> = props => {
|
|||
name={name}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
className={classNames({
|
||||
[classes.radioGroupInline]: variant === "inline"
|
||||
})}
|
||||
>
|
||||
{choices.length > 0 ? (
|
||||
choices.map(choice => (
|
||||
<FormControlLabel
|
||||
disabled={choice.disabled}
|
||||
value={choice.value}
|
||||
className={classes.radioLabel}
|
||||
className={classNames({
|
||||
[classes.radioLabel]: variant !== "inline",
|
||||
[classes.radioLabelInline]: variant === "inline"
|
||||
})}
|
||||
control={<Radio color="primary" />}
|
||||
label={choice.label}
|
||||
key={choice.value}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import grey from "@material-ui/core/colors/grey";
|
||||
import yellow from "@material-ui/core/colors/yellow";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import Typography, { TypographyProps } from "@material-ui/core/Typography";
|
||||
|
@ -34,6 +35,9 @@ const useStyles = makeStyles(
|
|||
},
|
||||
successDot: {
|
||||
"&:before": { backgroundColor: theme.palette.primary.main, ...dot }
|
||||
},
|
||||
unspecifiedDot: {
|
||||
"&:before": { backgroundColor: grey[500], ...dot }
|
||||
}
|
||||
};
|
||||
},
|
||||
|
@ -43,7 +47,7 @@ const useStyles = makeStyles(
|
|||
interface StatusLabelProps {
|
||||
className?: string;
|
||||
label: string | React.ReactNode;
|
||||
status: "success" | "neutral" | "error" | string;
|
||||
status: "success" | "neutral" | "unspecified" | "error" | string;
|
||||
typographyProps?: TypographyProps;
|
||||
}
|
||||
|
||||
|
@ -59,6 +63,7 @@ const StatusLabel: React.FC<StatusLabelProps> = props => {
|
|||
[className]: true,
|
||||
[classes.successDot]: status === "success",
|
||||
[classes.neutralDot]: status === "neutral",
|
||||
[classes.unspecifiedDot]: status === "unspecified",
|
||||
[classes.errorDot]: status === "error"
|
||||
})}
|
||||
>
|
||||
|
|
|
@ -4,6 +4,7 @@ import ExpansionPanelSummary from "@material-ui/core/ExpansionPanelSummary";
|
|||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
|
||||
import classNames from "classnames";
|
||||
import React from "react";
|
||||
|
||||
import { DateTime } from "../Date";
|
||||
|
@ -25,7 +26,7 @@ const useStyles = makeStyles(
|
|||
dateExpander: {
|
||||
color: theme.typography.caption.color,
|
||||
position: "absolute",
|
||||
right: theme.spacing(3)
|
||||
right: 0
|
||||
},
|
||||
dot: {
|
||||
backgroundColor: theme.palette.primary.main,
|
||||
|
@ -36,6 +37,7 @@ const useStyles = makeStyles(
|
|||
top: 6,
|
||||
width: 8
|
||||
},
|
||||
expanded: {},
|
||||
noExpander: {
|
||||
alignItems: "center",
|
||||
display: "flex",
|
||||
|
@ -43,12 +45,30 @@ const useStyles = makeStyles(
|
|||
width: "100%"
|
||||
},
|
||||
panel: {
|
||||
"&$expanded": {
|
||||
margin: 0
|
||||
},
|
||||
"&:before": {
|
||||
display: "none"
|
||||
},
|
||||
background: "none",
|
||||
margin: 0,
|
||||
width: "100%"
|
||||
},
|
||||
panelExpander: {
|
||||
"&$expanded": {
|
||||
margin: 0,
|
||||
minHeight: 0
|
||||
},
|
||||
"&> .MuiExpansionPanelSummary-content": {
|
||||
margin: 0
|
||||
},
|
||||
"&> .MuiExpansionPanelSummary-expandIcon": {
|
||||
padding: 0,
|
||||
right: theme.spacing(18)
|
||||
},
|
||||
margin: 0
|
||||
},
|
||||
root: {
|
||||
"&:last-child:after": {
|
||||
background: theme.palette.background.default,
|
||||
|
@ -90,10 +110,18 @@ export const TimelineEvent: React.FC<TimelineEventProps> = props => {
|
|||
<div className={classes.root}>
|
||||
<span className={classes.dot} />
|
||||
{children ? (
|
||||
<ExpansionPanel className={classes.panel} elevation={0}>
|
||||
<ExpansionPanelSummary expandIcon={<ExpandMoreIcon />}>
|
||||
<ExpansionPanel
|
||||
className={classNames(classes.panel, classes.expanded)}
|
||||
elevation={0}
|
||||
>
|
||||
<ExpansionPanelSummary
|
||||
className={classNames(classes.panelExpander, classes.expanded)}
|
||||
expandIcon={<ExpandMoreIcon />}
|
||||
>
|
||||
<Typography>{title}</Typography>
|
||||
<Typography className={classes.dateExpander}>{title}</Typography>
|
||||
<Typography className={classes.dateExpander}>
|
||||
<DateTime date={date} />
|
||||
</Typography>
|
||||
</ExpansionPanelSummary>
|
||||
<ExpansionPanelDetails>
|
||||
<Typography>{children}</Typography>
|
||||
|
|
|
@ -7,6 +7,7 @@ export const fragmentOrderEvent = gql`
|
|||
fragment OrderEventFragment on OrderEvent {
|
||||
id
|
||||
amount
|
||||
shippingCostsIncluded
|
||||
date
|
||||
email
|
||||
emailType
|
||||
|
@ -19,6 +20,14 @@ export const fragmentOrderEvent = gql`
|
|||
id
|
||||
email
|
||||
}
|
||||
lines {
|
||||
quantity
|
||||
orderLine {
|
||||
id
|
||||
productName
|
||||
variantName
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
|
@ -49,6 +58,23 @@ export const fragmentOrderLine = gql`
|
|||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const fragmentRefundOrderLine = gql`
|
||||
fragment RefundOrderLineFragment on OrderLine {
|
||||
id
|
||||
productName
|
||||
quantity
|
||||
unitPrice {
|
||||
gross {
|
||||
...Money
|
||||
}
|
||||
}
|
||||
thumbnail(size: 64) {
|
||||
url
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const fulfillmentFragment = gql`
|
||||
${fragmentOrderLine}
|
||||
fragment FulfillmentFragment on Fulfillment {
|
||||
|
|
|
@ -48,10 +48,24 @@ export interface OrderDetailsFragment_events_user {
|
|||
email: string;
|
||||
}
|
||||
|
||||
export interface OrderDetailsFragment_events_lines_orderLine {
|
||||
__typename: "OrderLine";
|
||||
id: string;
|
||||
productName: string;
|
||||
variantName: string;
|
||||
}
|
||||
|
||||
export interface OrderDetailsFragment_events_lines {
|
||||
__typename: "OrderEventOrderLineObject";
|
||||
quantity: number | null;
|
||||
orderLine: OrderDetailsFragment_events_lines_orderLine | null;
|
||||
}
|
||||
|
||||
export interface OrderDetailsFragment_events {
|
||||
__typename: "OrderEvent";
|
||||
id: string;
|
||||
amount: number | null;
|
||||
shippingCostsIncluded: boolean | null;
|
||||
date: any | null;
|
||||
email: string | null;
|
||||
emailType: OrderEventsEmailsEnum | null;
|
||||
|
@ -61,6 +75,7 @@ export interface OrderDetailsFragment_events {
|
|||
transactionReference: string | null;
|
||||
type: OrderEventsEnum | null;
|
||||
user: OrderDetailsFragment_events_user | null;
|
||||
lines: (OrderDetailsFragment_events_lines | null)[] | null;
|
||||
}
|
||||
|
||||
export interface OrderDetailsFragment_fulfillments_lines_orderLine_variant {
|
||||
|
|
|
@ -14,10 +14,24 @@ export interface OrderEventFragment_user {
|
|||
email: string;
|
||||
}
|
||||
|
||||
export interface OrderEventFragment_lines_orderLine {
|
||||
__typename: "OrderLine";
|
||||
id: string;
|
||||
productName: string;
|
||||
variantName: string;
|
||||
}
|
||||
|
||||
export interface OrderEventFragment_lines {
|
||||
__typename: "OrderEventOrderLineObject";
|
||||
quantity: number | null;
|
||||
orderLine: OrderEventFragment_lines_orderLine | null;
|
||||
}
|
||||
|
||||
export interface OrderEventFragment {
|
||||
__typename: "OrderEvent";
|
||||
id: string;
|
||||
amount: number | null;
|
||||
shippingCostsIncluded: boolean | null;
|
||||
date: any | null;
|
||||
email: string | null;
|
||||
emailType: OrderEventsEmailsEnum | null;
|
||||
|
@ -27,4 +41,5 @@ export interface OrderEventFragment {
|
|||
transactionReference: string | null;
|
||||
type: OrderEventsEnum | null;
|
||||
user: OrderEventFragment_user | null;
|
||||
lines: (OrderEventFragment_lines | null)[] | null;
|
||||
}
|
||||
|
|
32
src/fragments/types/RefundOrderLineFragment.ts
Normal file
32
src/fragments/types/RefundOrderLineFragment.ts
Normal file
|
@ -0,0 +1,32 @@
|
|||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
// ====================================================
|
||||
// GraphQL fragment: RefundOrderLineFragment
|
||||
// ====================================================
|
||||
|
||||
export interface RefundOrderLineFragment_unitPrice_gross {
|
||||
__typename: "Money";
|
||||
amount: number;
|
||||
currency: string;
|
||||
}
|
||||
|
||||
export interface RefundOrderLineFragment_unitPrice {
|
||||
__typename: "TaxedMoney";
|
||||
gross: RefundOrderLineFragment_unitPrice_gross;
|
||||
}
|
||||
|
||||
export interface RefundOrderLineFragment_thumbnail {
|
||||
__typename: "Image";
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface RefundOrderLineFragment {
|
||||
__typename: "OrderLine";
|
||||
id: string;
|
||||
productName: string;
|
||||
quantity: number;
|
||||
unitPrice: RefundOrderLineFragment_unitPrice | null;
|
||||
thumbnail: RefundOrderLineFragment_thumbnail | null;
|
||||
}
|
|
@ -233,7 +233,11 @@ const OrderDetailsPage: React.FC<OrderDetailsPageProps> = props => {
|
|||
/>
|
||||
<CardSpacer />
|
||||
<Metadata data={data} onChange={changeMetadata} />
|
||||
<OrderHistory history={order?.events} onNoteAdd={onNoteAdd} />
|
||||
<OrderHistory
|
||||
history={order?.events}
|
||||
orderCurrency={order?.total?.gross.currency}
|
||||
onNoteAdd={onNoteAdd}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<OrderCustomer
|
||||
|
|
|
@ -137,7 +137,11 @@ const OrderDraftPage: React.FC<OrderDraftPageProps> = props => {
|
|||
onOrderLineRemove={onOrderLineRemove}
|
||||
onShippingMethodEdit={onShippingMethodEdit}
|
||||
/>
|
||||
<OrderHistory history={order?.events} onNoteAdd={onNoteAdd} />
|
||||
<OrderHistory
|
||||
history={order?.events}
|
||||
orderCurrency={order?.total?.gross.currency}
|
||||
onNoteAdd={onNoteAdd}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<OrderCustomer
|
||||
|
|
|
@ -16,6 +16,7 @@ import StatusLabel from "@saleor/components/StatusLabel";
|
|||
import TableCellAvatar, {
|
||||
AVATAR_MARGIN
|
||||
} from "@saleor/components/TableCellAvatar";
|
||||
import { mergeRepeatedOrderLines } from "@saleor/orders/utils/data";
|
||||
import classNames from "classnames";
|
||||
import React from "react";
|
||||
import { FormattedMessage, useIntl } from "react-intl";
|
||||
|
@ -95,7 +96,10 @@ const OrderFulfillment: React.FC<OrderFulfillmentProps> = props => {
|
|||
|
||||
const intl = useIntl();
|
||||
|
||||
const lines = maybe(() => fulfillment.lines);
|
||||
const lines =
|
||||
fulfillment?.status === FulfillmentStatus.REFUNDED
|
||||
? mergeRepeatedOrderLines(fulfillment?.lines)
|
||||
: fulfillment?.lines;
|
||||
const status = maybe(() => fulfillment.status);
|
||||
const quantity = lines
|
||||
? lines.map(line => line.quantity).reduce((prev, curr) => prev + curr, 0)
|
||||
|
@ -119,6 +123,16 @@ const OrderFulfillment: React.FC<OrderFulfillmentProps> = props => {
|
|||
quantity
|
||||
}
|
||||
)
|
||||
: status === FulfillmentStatus.REFUNDED
|
||||
? intl.formatMessage(
|
||||
{
|
||||
defaultMessage: "Refunded ({quantity})",
|
||||
description: "refunded fulfillment, section header"
|
||||
},
|
||||
{
|
||||
quantity
|
||||
}
|
||||
)
|
||||
: intl.formatMessage(
|
||||
{
|
||||
defaultMessage: "Cancelled ({quantity})",
|
||||
|
@ -136,7 +150,11 @@ const OrderFulfillment: React.FC<OrderFulfillmentProps> = props => {
|
|||
</>
|
||||
}
|
||||
status={
|
||||
status === FulfillmentStatus.FULFILLED ? "success" : "error"
|
||||
status === FulfillmentStatus.FULFILLED
|
||||
? "success"
|
||||
: status === FulfillmentStatus.REFUNDED
|
||||
? "unspecified"
|
||||
: "error"
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
|
@ -239,9 +257,11 @@ const OrderFulfillment: React.FC<OrderFulfillmentProps> = props => {
|
|||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
{(fulfillment?.warehouse || fulfillment?.trackingNumber) && (
|
||||
<TableRow>
|
||||
<TableCell className={classes.infoRow} colSpan={numberOfColumns}>
|
||||
<Typography color="textSecondary" variant="body2">
|
||||
{fulfillment?.warehouse && (
|
||||
<FormattedMessage
|
||||
defaultMessage="Fulfilled from: {warehouseName}"
|
||||
description="fulfillment group"
|
||||
|
@ -254,11 +274,14 @@ const OrderFulfillment: React.FC<OrderFulfillmentProps> = props => {
|
|||
color="textPrimary"
|
||||
variant="body2"
|
||||
>
|
||||
{getStringOrPlaceholder(fulfillment?.warehouse?.name)}
|
||||
{getStringOrPlaceholder(
|
||||
fulfillment?.warehouse?.name
|
||||
)}
|
||||
</Typography>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Typography>
|
||||
<Typography color="textSecondary" variant="body2">
|
||||
{fulfillment?.trackingNumber && (
|
||||
|
@ -280,6 +303,7 @@ const OrderFulfillment: React.FC<OrderFulfillmentProps> = props => {
|
|||
</Typography>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)}
|
||||
</TableBody>
|
||||
</ResponsiveTable>
|
||||
{status === FulfillmentStatus.FULFILLED && !fulfillment.trackingNumber && (
|
||||
|
|
|
@ -2,6 +2,7 @@ import { makeStyles } from "@material-ui/core/styles";
|
|||
import Typography from "@material-ui/core/Typography";
|
||||
import Form from "@saleor/components/Form";
|
||||
import Hr from "@saleor/components/Hr";
|
||||
import Money from "@saleor/components/Money";
|
||||
import Skeleton from "@saleor/components/Skeleton";
|
||||
import {
|
||||
Timeline,
|
||||
|
@ -144,6 +145,16 @@ const getEventMessage = (event: OrderDetails_order_events, intl: IntlShape) => {
|
|||
quantity: event.quantity
|
||||
}
|
||||
);
|
||||
case OrderEventsEnum.FULFILLMENT_REFUNDED:
|
||||
return intl.formatMessage(
|
||||
{
|
||||
defaultMessage: "Order was refunded by {refundedBy}",
|
||||
description: "order history message"
|
||||
},
|
||||
{
|
||||
refundedBy: event.user ? event.user.email : null
|
||||
}
|
||||
);
|
||||
case OrderEventsEnum.FULFILLMENT_RESTOCKED_ITEMS:
|
||||
return intl.formatMessage(
|
||||
{
|
||||
|
@ -238,10 +249,16 @@ const getEventMessage = (event: OrderDetails_order_events, intl: IntlShape) => {
|
|||
|
||||
const useStyles = makeStyles(
|
||||
theme => ({
|
||||
eventSubtitle: {
|
||||
marginTop: theme.spacing(1)
|
||||
},
|
||||
header: {
|
||||
fontWeight: 500,
|
||||
marginBottom: theme.spacing(1)
|
||||
},
|
||||
linesTableCell: {
|
||||
paddingRight: theme.spacing(3)
|
||||
},
|
||||
root: { marginTop: theme.spacing(4) },
|
||||
user: {
|
||||
marginBottom: theme.spacing(1)
|
||||
|
@ -252,11 +269,12 @@ const useStyles = makeStyles(
|
|||
|
||||
interface OrderHistoryProps {
|
||||
history: OrderDetails_order_events[];
|
||||
orderCurrency: string;
|
||||
onNoteAdd: (data: FormData) => void;
|
||||
}
|
||||
|
||||
const OrderHistory: React.FC<OrderHistoryProps> = props => {
|
||||
const { history, onNoteAdd } = props;
|
||||
const { history, orderCurrency, onNoteAdd } = props;
|
||||
const classes = useStyles(props);
|
||||
|
||||
const intl = useIntl();
|
||||
|
@ -310,6 +328,74 @@ const OrderHistory: React.FC<OrderHistoryProps> = props => {
|
|||
/>
|
||||
);
|
||||
}
|
||||
if (event.type === OrderEventsEnum.FULFILLMENT_REFUNDED) {
|
||||
return (
|
||||
<TimelineEvent
|
||||
date={event.date}
|
||||
title={getEventMessage(event, intl)}
|
||||
key={event.id}
|
||||
>
|
||||
{event.lines && (
|
||||
<>
|
||||
<Typography
|
||||
variant="caption"
|
||||
color="textSecondary"
|
||||
className={classes.eventSubtitle}
|
||||
>
|
||||
<FormattedMessage defaultMessage="Products refunded" />
|
||||
</Typography>
|
||||
<table>
|
||||
<tbody>
|
||||
{event.lines.map(line => (
|
||||
<tr key={line.orderLine.id}>
|
||||
<td className={classes.linesTableCell}>
|
||||
{line.orderLine.productName}
|
||||
</td>
|
||||
<td className={classes.linesTableCell}>
|
||||
<Typography
|
||||
variant="caption"
|
||||
color="textSecondary"
|
||||
>
|
||||
{line.orderLine.variantName}
|
||||
</Typography>
|
||||
</td>
|
||||
<td className={classes.linesTableCell}>
|
||||
<Typography
|
||||
variant="caption"
|
||||
color="textSecondary"
|
||||
>
|
||||
{`qty: ${line.quantity}`}
|
||||
</Typography>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
<Typography
|
||||
variant="caption"
|
||||
color="textSecondary"
|
||||
className={classes.eventSubtitle}
|
||||
>
|
||||
<FormattedMessage defaultMessage="Refunded amount" />
|
||||
</Typography>
|
||||
{(event.amount || event.amount === 0) && (
|
||||
<Money
|
||||
money={{
|
||||
amount: event.amount,
|
||||
currency: orderCurrency
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{event.shippingCostsIncluded && (
|
||||
<Typography>
|
||||
<FormattedMessage defaultMessage="Shipment was refunded" />
|
||||
</Typography>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</TimelineEvent>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<TimelineEvent
|
||||
date={event.date}
|
||||
|
|
|
@ -58,6 +58,10 @@ const OrderPayment: React.FC<OrderPaymentProps> = props => {
|
|||
maybe(() => order.paymentStatus),
|
||||
intl
|
||||
);
|
||||
const refundedAmount =
|
||||
order?.totalCaptured &&
|
||||
order?.total?.gross &&
|
||||
subtractMoney(order.totalCaptured, order.total.gross);
|
||||
return (
|
||||
<Card>
|
||||
<CardTitle
|
||||
|
@ -226,6 +230,21 @@ const OrderPayment: React.FC<OrderPaymentProps> = props => {
|
|||
)}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<FormattedMessage
|
||||
defaultMessage="Refunded amount"
|
||||
description="order payment"
|
||||
/>
|
||||
</td>
|
||||
<td className={classes.textRight}>
|
||||
{refundedAmount?.amount === undefined ? (
|
||||
<Skeleton />
|
||||
) : (
|
||||
<Money money={refundedAmount} />
|
||||
)}
|
||||
</td>
|
||||
</tr>
|
||||
<tr className={classes.totalRow}>
|
||||
<td>
|
||||
<FormattedMessage
|
||||
|
|
|
@ -26,7 +26,6 @@ export interface OrderPaymentDialogProps {
|
|||
errors: OrderErrorFragment[];
|
||||
open: boolean;
|
||||
initial: number;
|
||||
variant: "capture" | "refund";
|
||||
onClose: () => void;
|
||||
onSubmit: (data: FormData) => void;
|
||||
}
|
||||
|
@ -36,7 +35,6 @@ const OrderPaymentDialog: React.FC<OrderPaymentDialogProps> = ({
|
|||
errors,
|
||||
open,
|
||||
initial,
|
||||
variant,
|
||||
onClose,
|
||||
onSubmit
|
||||
}) => {
|
||||
|
@ -56,14 +54,9 @@ const OrderPaymentDialog: React.FC<OrderPaymentDialogProps> = ({
|
|||
{({ data, change, submit }) => (
|
||||
<>
|
||||
<DialogTitle>
|
||||
{variant === "capture"
|
||||
? intl.formatMessage({
|
||||
{intl.formatMessage({
|
||||
defaultMessage: "Capture Payment",
|
||||
description: "dialog header"
|
||||
})
|
||||
: intl.formatMessage({
|
||||
defaultMessage: "Refund Payment",
|
||||
description: "dialog header"
|
||||
})}
|
||||
</DialogTitle>
|
||||
<DialogContent>
|
||||
|
|
71
src/orders/components/OrderRefund/OrderRefund.tsx
Normal file
71
src/orders/components/OrderRefund/OrderRefund.tsx
Normal file
|
@ -0,0 +1,71 @@
|
|||
import { makeStyles } from "@material-ui/core";
|
||||
import Card from "@material-ui/core/Card";
|
||||
import CardContent from "@material-ui/core/CardContent";
|
||||
import CardTitle from "@saleor/components/CardTitle";
|
||||
import RadioGroupField from "@saleor/components/RadioGroupField";
|
||||
import React from "react";
|
||||
import { defineMessages, useIntl } from "react-intl";
|
||||
|
||||
import { OrderRefundFormData, OrderRefundType } from "../OrderRefundPage/form";
|
||||
|
||||
const useStyles = makeStyles(
|
||||
{
|
||||
cartContent: { paddingBottom: 0 }
|
||||
},
|
||||
{ name: "OrderRefund" }
|
||||
);
|
||||
|
||||
interface OrderRefundProps {
|
||||
data: OrderRefundFormData;
|
||||
disabled: boolean;
|
||||
onChange: (event: React.ChangeEvent<any>) => void;
|
||||
}
|
||||
|
||||
const messages = defineMessages({
|
||||
refundMiscellaneous: {
|
||||
defaultMessage: "Miscellaneous Refund",
|
||||
description: "refund type"
|
||||
},
|
||||
refundProducts: {
|
||||
defaultMessage: "Refund Products",
|
||||
description: "refund type"
|
||||
}
|
||||
});
|
||||
|
||||
const OrderRefund: React.FC<OrderRefundProps> = props => {
|
||||
const { data, disabled, onChange } = props;
|
||||
const classes = useStyles(props);
|
||||
const intl = useIntl();
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardTitle
|
||||
title={intl.formatMessage({
|
||||
defaultMessage: "Refund Order",
|
||||
description: "section header"
|
||||
})}
|
||||
/>
|
||||
<CardContent className={classes.cartContent}>
|
||||
<RadioGroupField
|
||||
choices={[
|
||||
{
|
||||
label: intl.formatMessage(messages.refundProducts),
|
||||
value: OrderRefundType.PRODUCTS
|
||||
},
|
||||
{
|
||||
label: intl.formatMessage(messages.refundMiscellaneous),
|
||||
value: OrderRefundType.MISCELLANEOUS
|
||||
}
|
||||
]}
|
||||
disabled={disabled}
|
||||
name={"type" as keyof FormData}
|
||||
value={data.type}
|
||||
onChange={onChange}
|
||||
variant="inline"
|
||||
/>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
OrderRefund.displayName = "OrderRefund";
|
||||
export default OrderRefund;
|
2
src/orders/components/OrderRefund/index.ts
Normal file
2
src/orders/components/OrderRefund/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
|||
export * from "./OrderRefund";
|
||||
export { default } from "./OrderRefund";
|
381
src/orders/components/OrderRefundAmount/OrderRefundAmount.tsx
Normal file
381
src/orders/components/OrderRefundAmount/OrderRefundAmount.tsx
Normal file
|
@ -0,0 +1,381 @@
|
|||
import { makeStyles, RadioGroup } from "@material-ui/core";
|
||||
import Button from "@material-ui/core/Button";
|
||||
import Card from "@material-ui/core/Card";
|
||||
import CardContent from "@material-ui/core/CardContent";
|
||||
import FormControlLabel from "@material-ui/core/FormControlLabel";
|
||||
import Radio from "@material-ui/core/Radio";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import CardSpacer from "@saleor/components/CardSpacer";
|
||||
import CardTitle from "@saleor/components/CardTitle";
|
||||
import ControlledCheckbox from "@saleor/components/ControlledCheckbox";
|
||||
import Hr from "@saleor/components/Hr";
|
||||
import { IMoney } from "@saleor/components/Money";
|
||||
import PriceField from "@saleor/components/PriceField";
|
||||
import { OrderErrorFragment } from "@saleor/fragments/types/OrderErrorFragment";
|
||||
import { OrderRefundData_order } from "@saleor/orders/types/OrderRefundData";
|
||||
import {
|
||||
getAllFulfillmentLinesPriceSum,
|
||||
getPreviouslyRefundedPrice,
|
||||
getRefundedLinesPriceSum
|
||||
} from "@saleor/orders/utils/data";
|
||||
import { getFormErrors } from "@saleor/utils/errors";
|
||||
import getOrderErrorMessage from "@saleor/utils/errors/order";
|
||||
import React from "react";
|
||||
import { FormattedMessage, useIntl } from "react-intl";
|
||||
|
||||
import OrderRefundAmountValues, {
|
||||
OrderRefundAmountValuesProps
|
||||
} from "../OrderRefundAmountValues";
|
||||
import {
|
||||
OrderRefundAmountCalculationMode,
|
||||
OrderRefundFormData,
|
||||
OrderRefundType
|
||||
} from "../OrderRefundPage/form";
|
||||
|
||||
const getMiscellaneousAmountValues = (
|
||||
order: OrderRefundData_order
|
||||
): OrderRefundAmountValuesProps => {
|
||||
const authorizedAmount = order?.total?.gross;
|
||||
const previouslyRefunded = getPreviouslyRefundedPrice(order);
|
||||
const maxRefund = order?.totalCaptured;
|
||||
|
||||
return {
|
||||
authorizedAmount,
|
||||
maxRefund,
|
||||
previouslyRefunded
|
||||
};
|
||||
};
|
||||
|
||||
const getProductsAmountValues = (
|
||||
order: OrderRefundData_order,
|
||||
data: OrderRefundFormData
|
||||
): OrderRefundAmountValuesProps => {
|
||||
const authorizedAmount = order?.total?.gross;
|
||||
const shipmentCost =
|
||||
authorizedAmount?.currency &&
|
||||
(order?.shippingPrice?.gross || {
|
||||
amount: 0,
|
||||
currency: authorizedAmount?.currency
|
||||
});
|
||||
const previouslyRefunded = getPreviouslyRefundedPrice(order);
|
||||
const maxRefund = order?.totalCaptured;
|
||||
const refundedLinesSum = getRefundedLinesPriceSum(
|
||||
order?.lines,
|
||||
data.refundedProductQuantities
|
||||
);
|
||||
const allFulfillmentLinesSum = getAllFulfillmentLinesPriceSum(
|
||||
order?.fulfillments,
|
||||
data.refundedFulfilledProductQuantities
|
||||
);
|
||||
const allLinesSum = refundedLinesSum + allFulfillmentLinesSum;
|
||||
const calculatedTotalAmount = data.refundShipmentCosts
|
||||
? allLinesSum + shipmentCost?.amount
|
||||
: allLinesSum;
|
||||
const selectedProductsValue = authorizedAmount?.currency && {
|
||||
amount: allLinesSum,
|
||||
currency: authorizedAmount.currency
|
||||
};
|
||||
const proposedRefundAmount = authorizedAmount?.currency && {
|
||||
amount: calculatedTotalAmount,
|
||||
currency: authorizedAmount.currency
|
||||
};
|
||||
const refundTotalAmount = authorizedAmount?.currency && {
|
||||
amount: calculatedTotalAmount,
|
||||
currency: authorizedAmount.currency
|
||||
};
|
||||
|
||||
return {
|
||||
authorizedAmount,
|
||||
maxRefund,
|
||||
previouslyRefunded,
|
||||
proposedRefundAmount,
|
||||
refundTotalAmount,
|
||||
selectedProductsValue,
|
||||
shipmentCost
|
||||
};
|
||||
};
|
||||
|
||||
const useStyles = makeStyles(
|
||||
theme => ({
|
||||
hr: {
|
||||
margin: theme.spacing(1, 0)
|
||||
},
|
||||
maxRefundRow: {
|
||||
fontWeight: 600
|
||||
},
|
||||
priceField: {
|
||||
marginTop: theme.spacing(2)
|
||||
},
|
||||
refundButton: {
|
||||
marginTop: theme.spacing(2)
|
||||
},
|
||||
refundCaution: {
|
||||
marginTop: theme.spacing(1)
|
||||
},
|
||||
root: {
|
||||
...theme.typography.body1,
|
||||
lineHeight: 1.9,
|
||||
width: "100%"
|
||||
},
|
||||
textRight: {
|
||||
textAlign: "right"
|
||||
}
|
||||
}),
|
||||
{ name: "OrderRefundAmount" }
|
||||
);
|
||||
|
||||
interface RefundAmountInputProps {
|
||||
data: OrderRefundFormData;
|
||||
maxRefund: IMoney;
|
||||
currencySymbol: string;
|
||||
amountTooSmall: boolean;
|
||||
amountTooBig: boolean;
|
||||
disabled: boolean;
|
||||
errors: OrderErrorFragment[];
|
||||
onChange: (event: React.ChangeEvent<any>) => void;
|
||||
}
|
||||
|
||||
const RefundAmountInput: React.FC<RefundAmountInputProps> = props => {
|
||||
const {
|
||||
data,
|
||||
maxRefund,
|
||||
amountTooSmall,
|
||||
amountTooBig,
|
||||
currencySymbol,
|
||||
disabled,
|
||||
errors,
|
||||
onChange
|
||||
} = props;
|
||||
const intl = useIntl();
|
||||
const classes = useStyles(props);
|
||||
|
||||
const formErrors = getFormErrors(["amount"], errors);
|
||||
|
||||
return (
|
||||
<PriceField
|
||||
disabled={disabled}
|
||||
onChange={onChange}
|
||||
currencySymbol={currencySymbol}
|
||||
name={"amount" as keyof FormData}
|
||||
value={data.amount}
|
||||
label={intl.formatMessage({
|
||||
defaultMessage: "Amount",
|
||||
description: "order refund amount, input label"
|
||||
})}
|
||||
className={classes.priceField}
|
||||
InputProps={{ inputProps: { max: maxRefund?.amount } }}
|
||||
inputProps={{
|
||||
"data-test": "amountInput",
|
||||
max: maxRefund?.amount
|
||||
}}
|
||||
error={!!formErrors.amount || amountTooSmall || amountTooBig}
|
||||
hint={
|
||||
getOrderErrorMessage(formErrors.amount, intl) ||
|
||||
(amountTooSmall &&
|
||||
intl.formatMessage({
|
||||
defaultMessage: "Amount must be bigger than 0"
|
||||
})) ||
|
||||
(amountTooBig &&
|
||||
intl.formatMessage({
|
||||
defaultMessage: "Amount cannot be bigger than max refund"
|
||||
}))
|
||||
}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
interface OrderRefundAmountProps {
|
||||
data: OrderRefundFormData;
|
||||
order: OrderRefundData_order;
|
||||
disabled: boolean;
|
||||
errors: OrderErrorFragment[];
|
||||
onChange: (event: React.ChangeEvent<any>) => void;
|
||||
onRefund: () => void;
|
||||
}
|
||||
|
||||
const OrderRefundAmount: React.FC<OrderRefundAmountProps> = props => {
|
||||
const { data, order, disabled, errors, onChange, onRefund } = props;
|
||||
const classes = useStyles(props);
|
||||
const intl = useIntl();
|
||||
|
||||
const amountCurrency = order?.total?.gross?.currency;
|
||||
|
||||
const {
|
||||
authorizedAmount,
|
||||
maxRefund,
|
||||
previouslyRefunded,
|
||||
proposedRefundAmount,
|
||||
refundTotalAmount,
|
||||
selectedProductsValue,
|
||||
shipmentCost
|
||||
} =
|
||||
data.type === OrderRefundType.PRODUCTS
|
||||
? getProductsAmountValues(order, data)
|
||||
: getMiscellaneousAmountValues(order);
|
||||
|
||||
const selectedRefundAmount =
|
||||
data.type === OrderRefundType.PRODUCTS &&
|
||||
data.amountCalculationMode === OrderRefundAmountCalculationMode.AUTOMATIC
|
||||
? refundTotalAmount?.amount
|
||||
: data.amount;
|
||||
|
||||
const isAmountTooSmall = selectedRefundAmount && selectedRefundAmount <= 0;
|
||||
const isAmountTooBig = selectedRefundAmount > maxRefund?.amount;
|
||||
|
||||
const disableRefundButton =
|
||||
!selectedRefundAmount || isAmountTooSmall || isAmountTooBig;
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardTitle
|
||||
title={intl.formatMessage({
|
||||
defaultMessage: "Refunded Amount",
|
||||
description: "section header"
|
||||
})}
|
||||
/>
|
||||
<CardContent>
|
||||
{data.type === OrderRefundType.PRODUCTS && (
|
||||
<RadioGroup
|
||||
value={data.amountCalculationMode}
|
||||
onChange={onChange}
|
||||
name="amountCalculationMode"
|
||||
>
|
||||
<FormControlLabel
|
||||
disabled={disabled}
|
||||
value={OrderRefundAmountCalculationMode.AUTOMATIC}
|
||||
control={<Radio color="primary" />}
|
||||
label={intl.formatMessage({
|
||||
defaultMessage: "Automatic Amount",
|
||||
description: "label"
|
||||
})}
|
||||
/>
|
||||
{data.amountCalculationMode ===
|
||||
OrderRefundAmountCalculationMode.AUTOMATIC && (
|
||||
<>
|
||||
<ControlledCheckbox
|
||||
checked={data.refundShipmentCosts}
|
||||
label={intl.formatMessage({
|
||||
defaultMessage: "Refund shipment costs",
|
||||
description: "checkbox"
|
||||
})}
|
||||
name="refundShipmentCosts"
|
||||
onChange={onChange}
|
||||
/>
|
||||
<OrderRefundAmountValues
|
||||
authorizedAmount={authorizedAmount}
|
||||
previouslyRefunded={previouslyRefunded}
|
||||
maxRefund={maxRefund}
|
||||
selectedProductsValue={selectedProductsValue}
|
||||
refundTotalAmount={refundTotalAmount}
|
||||
shipmentCost={data.refundShipmentCosts && shipmentCost}
|
||||
/>
|
||||
<CardSpacer />
|
||||
</>
|
||||
)}
|
||||
<Hr className={classes.hr} />
|
||||
<FormControlLabel
|
||||
disabled={disabled}
|
||||
value={OrderRefundAmountCalculationMode.MANUAL}
|
||||
control={<Radio color="primary" />}
|
||||
label={intl.formatMessage({
|
||||
defaultMessage: "Manual Amount",
|
||||
description: "label"
|
||||
})}
|
||||
/>
|
||||
{data.amountCalculationMode ===
|
||||
OrderRefundAmountCalculationMode.MANUAL && (
|
||||
<>
|
||||
<ControlledCheckbox
|
||||
disabled={disabled}
|
||||
checked={data.refundShipmentCosts}
|
||||
label={intl.formatMessage({
|
||||
defaultMessage: "Refund shipment costs",
|
||||
description: "checkbox"
|
||||
})}
|
||||
name="refundShipmentCosts"
|
||||
onChange={onChange}
|
||||
/>
|
||||
<OrderRefundAmountValues
|
||||
authorizedAmount={authorizedAmount}
|
||||
previouslyRefunded={previouslyRefunded}
|
||||
maxRefund={maxRefund}
|
||||
selectedProductsValue={selectedProductsValue}
|
||||
proposedRefundAmount={proposedRefundAmount}
|
||||
shipmentCost={data.refundShipmentCosts && shipmentCost}
|
||||
/>
|
||||
<RefundAmountInput
|
||||
data={data}
|
||||
maxRefund={maxRefund}
|
||||
amountTooSmall={isAmountTooSmall}
|
||||
amountTooBig={isAmountTooBig}
|
||||
currencySymbol={amountCurrency}
|
||||
disabled={disabled}
|
||||
onChange={onChange}
|
||||
errors={errors}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</RadioGroup>
|
||||
)}
|
||||
{data.type === OrderRefundType.MISCELLANEOUS && (
|
||||
<>
|
||||
<OrderRefundAmountValues
|
||||
authorizedAmount={authorizedAmount}
|
||||
previouslyRefunded={previouslyRefunded}
|
||||
maxRefund={maxRefund}
|
||||
/>
|
||||
<RefundAmountInput
|
||||
data={data}
|
||||
maxRefund={maxRefund}
|
||||
amountTooSmall={isAmountTooSmall}
|
||||
amountTooBig={isAmountTooBig}
|
||||
currencySymbol={amountCurrency}
|
||||
disabled={disabled}
|
||||
onChange={onChange}
|
||||
errors={errors}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
<Button
|
||||
type="submit"
|
||||
color="primary"
|
||||
variant="contained"
|
||||
fullWidth
|
||||
size="large"
|
||||
onClick={onRefund}
|
||||
className={classes.refundButton}
|
||||
disabled={disabled || disableRefundButton}
|
||||
data-test="submit"
|
||||
>
|
||||
{!disableRefundButton ? (
|
||||
<FormattedMessage
|
||||
defaultMessage="Refund {currency} {amount}"
|
||||
description="order refund amount, input button"
|
||||
values={{
|
||||
amount: Number(selectedRefundAmount).toFixed(2),
|
||||
currency: amountCurrency
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<FormattedMessage
|
||||
defaultMessage="Refund"
|
||||
description="order refund amount, input button"
|
||||
/>
|
||||
)}
|
||||
</Button>
|
||||
<Typography
|
||||
variant="caption"
|
||||
color="textSecondary"
|
||||
className={classes.refundCaution}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Refunded items can’t be fulfilled"
|
||||
description="order refund amount"
|
||||
/>
|
||||
</Typography>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
OrderRefundAmount.displayName = "OrderRefundAmount";
|
||||
export default OrderRefundAmount;
|
2
src/orders/components/OrderRefundAmount/index.ts
Normal file
2
src/orders/components/OrderRefundAmount/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
|||
export * from "./OrderRefundAmount";
|
||||
export { default } from "./OrderRefundAmount";
|
|
@ -0,0 +1,153 @@
|
|||
import { makeStyles } from "@material-ui/core";
|
||||
import Money, { IMoney } from "@saleor/components/Money";
|
||||
import Skeleton from "@saleor/components/Skeleton";
|
||||
import React from "react";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
|
||||
const useStyles = makeStyles(
|
||||
theme => ({
|
||||
highlightedRow: {
|
||||
fontWeight: 600
|
||||
},
|
||||
root: {
|
||||
...theme.typography.body1,
|
||||
lineHeight: 1.9,
|
||||
width: "100%"
|
||||
},
|
||||
textRight: {
|
||||
minWidth: 30,
|
||||
textAlign: "right"
|
||||
}
|
||||
}),
|
||||
{ name: "OrderRefundAmountValues" }
|
||||
);
|
||||
|
||||
export interface OrderRefundAmountValuesProps {
|
||||
authorizedAmount: IMoney;
|
||||
shipmentCost?: IMoney;
|
||||
selectedProductsValue?: IMoney;
|
||||
previouslyRefunded: IMoney;
|
||||
maxRefund: IMoney;
|
||||
proposedRefundAmount?: IMoney;
|
||||
refundTotalAmount?: IMoney;
|
||||
}
|
||||
|
||||
const OrderRefundAmountValues: React.FC<OrderRefundAmountValuesProps> = ({
|
||||
authorizedAmount,
|
||||
shipmentCost,
|
||||
selectedProductsValue,
|
||||
previouslyRefunded,
|
||||
maxRefund,
|
||||
proposedRefundAmount,
|
||||
refundTotalAmount
|
||||
}) => {
|
||||
const classes = useStyles({});
|
||||
|
||||
return (
|
||||
<table className={classes.root}>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<FormattedMessage
|
||||
defaultMessage="Authorized Amount"
|
||||
description="order refund amount"
|
||||
/>
|
||||
</td>
|
||||
<td className={classes.textRight}>
|
||||
{authorizedAmount?.amount !== undefined ? (
|
||||
<Money money={authorizedAmount} />
|
||||
) : (
|
||||
<Skeleton />
|
||||
)}
|
||||
</td>
|
||||
</tr>
|
||||
{shipmentCost?.amount !== undefined && (
|
||||
<tr>
|
||||
<td>
|
||||
<FormattedMessage
|
||||
defaultMessage="Shipment cost"
|
||||
description="order refund amount"
|
||||
/>
|
||||
</td>
|
||||
<td className={classes.textRight}>
|
||||
<Money money={shipmentCost} />
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
{selectedProductsValue?.amount !== undefined && (
|
||||
<tr>
|
||||
<td>
|
||||
<FormattedMessage
|
||||
defaultMessage="Selected products value"
|
||||
description="order refund amount"
|
||||
/>
|
||||
</td>
|
||||
<td className={classes.textRight}>
|
||||
<Money money={selectedProductsValue} />
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
<tr>
|
||||
<td>
|
||||
<FormattedMessage
|
||||
defaultMessage="Previously refunded"
|
||||
description="order refund amount"
|
||||
/>
|
||||
</td>
|
||||
<td className={classes.textRight}>
|
||||
{previouslyRefunded?.amount !== undefined ? (
|
||||
<>
|
||||
<Money money={previouslyRefunded} />
|
||||
</>
|
||||
) : (
|
||||
<Skeleton />
|
||||
)}
|
||||
</td>
|
||||
</tr>
|
||||
<tr className={classes.highlightedRow}>
|
||||
<td>
|
||||
<FormattedMessage
|
||||
defaultMessage="Max Refund"
|
||||
description="order refund amount"
|
||||
/>
|
||||
</td>
|
||||
<td className={classes.textRight}>
|
||||
{maxRefund?.amount !== undefined ? (
|
||||
<Money money={maxRefund} />
|
||||
) : (
|
||||
<Skeleton />
|
||||
)}
|
||||
</td>
|
||||
</tr>
|
||||
{proposedRefundAmount?.amount !== undefined && (
|
||||
<tr className={classes.highlightedRow}>
|
||||
<td>
|
||||
<FormattedMessage
|
||||
defaultMessage="Proposed refund amount"
|
||||
description="order refund amount"
|
||||
/>
|
||||
</td>
|
||||
<td className={classes.textRight}>
|
||||
<Money money={proposedRefundAmount} />
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
{refundTotalAmount?.amount !== undefined && (
|
||||
<tr className={classes.highlightedRow}>
|
||||
<td>
|
||||
<FormattedMessage
|
||||
defaultMessage="Refund total amount"
|
||||
description="order refund amount"
|
||||
/>
|
||||
</td>
|
||||
<td className={classes.textRight}>
|
||||
<Money money={refundTotalAmount} />
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
);
|
||||
};
|
||||
OrderRefundAmountValues.displayName = "OrderRefundAmountValues";
|
||||
export default OrderRefundAmountValues;
|
2
src/orders/components/OrderRefundAmountValues/index.ts
Normal file
2
src/orders/components/OrderRefundAmountValues/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
|||
export * from "./OrderRefundAmountValues";
|
||||
export { default } from "./OrderRefundAmountValues";
|
|
@ -0,0 +1,246 @@
|
|||
import { makeStyles } from "@material-ui/core";
|
||||
import Button from "@material-ui/core/Button";
|
||||
import Card from "@material-ui/core/Card";
|
||||
import CardContent from "@material-ui/core/CardContent";
|
||||
import Table from "@material-ui/core/Table";
|
||||
import TableBody from "@material-ui/core/TableBody";
|
||||
import TableCell from "@material-ui/core/TableCell";
|
||||
import TableHead from "@material-ui/core/TableHead";
|
||||
import TableRow from "@material-ui/core/TableRow";
|
||||
import TextField from "@material-ui/core/TextField";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import { CSSProperties } from "@material-ui/styles";
|
||||
import CardTitle from "@saleor/components/CardTitle";
|
||||
import Money from "@saleor/components/Money";
|
||||
import Skeleton from "@saleor/components/Skeleton";
|
||||
import TableCellAvatar from "@saleor/components/TableCellAvatar";
|
||||
import { FormsetChange } from "@saleor/hooks/useFormset";
|
||||
import { renderCollection } from "@saleor/misc";
|
||||
import { OrderRefundData_order_fulfillments } from "@saleor/orders/types/OrderRefundData";
|
||||
import React from "react";
|
||||
import { FormattedMessage, useIntl } from "react-intl";
|
||||
|
||||
import { OrderRefundFormData } from "../OrderRefundPage/form";
|
||||
|
||||
const useStyles = makeStyles(
|
||||
theme => {
|
||||
const inputPadding: CSSProperties = {
|
||||
paddingBottom: theme.spacing(2),
|
||||
paddingTop: theme.spacing(2)
|
||||
};
|
||||
|
||||
return {
|
||||
cartContent: {
|
||||
paddingBottom: 0,
|
||||
paddingTop: 0
|
||||
},
|
||||
colQuantity: {
|
||||
textAlign: "right",
|
||||
width: 210
|
||||
},
|
||||
notice: {
|
||||
marginBottom: theme.spacing(1),
|
||||
marginTop: theme.spacing(2)
|
||||
},
|
||||
orderNumber: {
|
||||
display: "inline",
|
||||
marginLeft: theme.spacing(1)
|
||||
},
|
||||
quantityInnerInput: {
|
||||
...inputPadding
|
||||
},
|
||||
quantityInnerInputNoRemaining: {
|
||||
paddingRight: 0
|
||||
},
|
||||
remainingQuantity: {
|
||||
...inputPadding,
|
||||
color: theme.palette.text.secondary,
|
||||
whiteSpace: "nowrap"
|
||||
},
|
||||
setMaximalQuantityButton: {
|
||||
marginTop: theme.spacing(1)
|
||||
}
|
||||
};
|
||||
},
|
||||
{ name: "OrderRefundFulfilledProducts" }
|
||||
);
|
||||
|
||||
interface OrderRefundFulfilledProductsProps {
|
||||
fulfillment: OrderRefundData_order_fulfillments;
|
||||
data: OrderRefundFormData;
|
||||
disabled: boolean;
|
||||
orderNumber: string;
|
||||
onRefundedProductQuantityChange: FormsetChange<string>;
|
||||
onSetMaximalQuantities: () => void;
|
||||
}
|
||||
|
||||
const OrderRefundFulfilledProducts: React.FC<OrderRefundFulfilledProductsProps> = props => {
|
||||
const {
|
||||
fulfillment,
|
||||
data,
|
||||
disabled,
|
||||
orderNumber,
|
||||
onRefundedProductQuantityChange,
|
||||
onSetMaximalQuantities
|
||||
} = props;
|
||||
const classes = useStyles(props);
|
||||
const intl = useIntl();
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardTitle
|
||||
title={
|
||||
<>
|
||||
{intl.formatMessage({
|
||||
defaultMessage: "Fulfillment",
|
||||
description: "section header"
|
||||
})}
|
||||
{fulfillment && (
|
||||
<Typography className={classes.orderNumber} variant="body1">
|
||||
{`#${orderNumber}-${fulfillment?.fulfillmentOrder}`}
|
||||
</Typography>
|
||||
)}
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<CardContent className={classes.cartContent}>
|
||||
<Button
|
||||
className={classes.setMaximalQuantityButton}
|
||||
color="primary"
|
||||
onClick={onSetMaximalQuantities}
|
||||
data-test="setMaximalQuantityFulfilledButton"
|
||||
data-test-id={fulfillment?.id}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Set maximal quantities"
|
||||
description="button"
|
||||
/>
|
||||
</Button>
|
||||
</CardContent>
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell>
|
||||
<FormattedMessage
|
||||
defaultMessage="Product"
|
||||
description="tabel column header"
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<FormattedMessage
|
||||
defaultMessage="Price"
|
||||
description="tabel column header"
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<FormattedMessage
|
||||
defaultMessage="Refunded Qty"
|
||||
description="tabel column header"
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<FormattedMessage
|
||||
defaultMessage="Total"
|
||||
description="tabel column header"
|
||||
/>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{renderCollection(
|
||||
fulfillment?.lines,
|
||||
line => {
|
||||
const selectedLineQuantity = data.refundedFulfilledProductQuantities.find(
|
||||
refundedLine => refundedLine.id === line.id
|
||||
);
|
||||
const isError =
|
||||
Number(selectedLineQuantity?.value) > line?.quantity ||
|
||||
Number(selectedLineQuantity?.value) < 0;
|
||||
|
||||
return (
|
||||
<TableRow key={line?.id}>
|
||||
<TableCellAvatar thumbnail={line?.orderLine?.thumbnail?.url}>
|
||||
{line?.orderLine?.productName ? (
|
||||
line?.orderLine?.productName
|
||||
) : (
|
||||
<Skeleton />
|
||||
)}
|
||||
</TableCellAvatar>
|
||||
<TableCell>
|
||||
{line?.orderLine?.unitPrice ? (
|
||||
<Money money={line?.orderLine?.unitPrice.gross} />
|
||||
) : (
|
||||
<Skeleton />
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell className={classes.colQuantity}>
|
||||
{line?.quantity ? (
|
||||
<TextField
|
||||
disabled={disabled}
|
||||
type="number"
|
||||
inputProps={{
|
||||
className: classes.quantityInnerInput,
|
||||
"data-test": "quantityInput",
|
||||
"data-test-id": line?.id,
|
||||
max: (line?.quantity).toString(),
|
||||
min: 0,
|
||||
style: { textAlign: "right" }
|
||||
}}
|
||||
fullWidth
|
||||
value={selectedLineQuantity?.value}
|
||||
onChange={event =>
|
||||
onRefundedProductQuantityChange(
|
||||
line.id,
|
||||
event.target.value
|
||||
)
|
||||
}
|
||||
InputProps={{
|
||||
endAdornment: line?.quantity && (
|
||||
<div className={classes.remainingQuantity}>
|
||||
/ {line?.quantity}
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
error={isError}
|
||||
helperText={
|
||||
isError &&
|
||||
intl.formatMessage({
|
||||
defaultMessage: "Improper value",
|
||||
description: "error message"
|
||||
})
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
<Skeleton />
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{(line?.quantity && line?.orderLine?.unitPrice.gross && (
|
||||
<Money
|
||||
money={{
|
||||
...line?.orderLine.unitPrice.gross,
|
||||
amount:
|
||||
(line?.orderLine.unitPrice.gross.amount || 0) *
|
||||
Number(selectedLineQuantity?.value)
|
||||
}}
|
||||
/>
|
||||
)) || <Skeleton />}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
},
|
||||
() => (
|
||||
<TableRow>
|
||||
<TableCell colSpan={4}>
|
||||
<FormattedMessage defaultMessage="No products found" />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
OrderRefundFulfilledProducts.displayName = "OrderRefundFulfilledProducts";
|
||||
export default OrderRefundFulfilledProducts;
|
|
@ -0,0 +1,2 @@
|
|||
export * from "./OrderRefundFulfilledProducts";
|
||||
export { default } from "./OrderRefundFulfilledProducts";
|
|
@ -0,0 +1,28 @@
|
|||
import placeholderImage from "@assets/images/placeholder60x60.png";
|
||||
import Decorator from "@saleor/storybook/Decorator";
|
||||
import { storiesOf } from "@storybook/react";
|
||||
import React from "react";
|
||||
|
||||
import { orderToRefund } from "./fixtures";
|
||||
import { OrderRefundType } from "./form";
|
||||
import OrderRefundPage, { OrderRefundPageProps } from "./OrderRefundPage";
|
||||
|
||||
const props: OrderRefundPageProps = {
|
||||
disabled: false,
|
||||
errors: [],
|
||||
onBack: () => undefined,
|
||||
onSubmit: () => undefined,
|
||||
order: orderToRefund(placeholderImage)
|
||||
};
|
||||
|
||||
storiesOf("Views / Orders / Refund order", module)
|
||||
.addDecorator(Decorator)
|
||||
.add("products", () => (
|
||||
<OrderRefundPage {...props} defaultType={OrderRefundType.PRODUCTS} />
|
||||
))
|
||||
.add("miscellaneous", () => (
|
||||
<OrderRefundPage {...props} defaultType={OrderRefundType.MISCELLANEOUS} />
|
||||
))
|
||||
.add("loading", () => (
|
||||
<OrderRefundPage {...props} disabled={true} order={undefined} />
|
||||
));
|
147
src/orders/components/OrderRefundPage/OrderRefundPage.tsx
Normal file
147
src/orders/components/OrderRefundPage/OrderRefundPage.tsx
Normal file
|
@ -0,0 +1,147 @@
|
|||
import AppHeader from "@saleor/components/AppHeader";
|
||||
import CardSpacer from "@saleor/components/CardSpacer";
|
||||
import Container from "@saleor/components/Container";
|
||||
import Grid from "@saleor/components/Grid";
|
||||
import PageHeader from "@saleor/components/PageHeader";
|
||||
import { OrderErrorFragment } from "@saleor/fragments/types/OrderErrorFragment";
|
||||
import { SubmitPromise } from "@saleor/hooks/useForm";
|
||||
import { renderCollection } from "@saleor/misc";
|
||||
import { OrderRefundData_order } from "@saleor/orders/types/OrderRefundData";
|
||||
import { FulfillmentStatus } from "@saleor/types/globalTypes";
|
||||
import React from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
|
||||
import OrderRefund from "../OrderRefund";
|
||||
import OrderRefundAmount from "../OrderRefundAmount";
|
||||
import OrderRefundFulfilledProducts from "../OrderRefundFulfilledProducts";
|
||||
import OrderRefundUnfulfilledProducts from "../OrderRefundUnfulfilledProducts";
|
||||
import OrderRefundForm, {
|
||||
OrderRefundSubmitData,
|
||||
OrderRefundType
|
||||
} from "./form";
|
||||
|
||||
export interface OrderRefundPageProps {
|
||||
order: OrderRefundData_order;
|
||||
defaultType?: OrderRefundType;
|
||||
disabled: boolean;
|
||||
errors: OrderErrorFragment[];
|
||||
onBack: () => void;
|
||||
onSubmit: (data: OrderRefundSubmitData) => SubmitPromise;
|
||||
}
|
||||
|
||||
const OrderRefundPage: React.FC<OrderRefundPageProps> = props => {
|
||||
const {
|
||||
order,
|
||||
defaultType = OrderRefundType.PRODUCTS,
|
||||
disabled,
|
||||
errors = [],
|
||||
onBack,
|
||||
onSubmit
|
||||
} = props;
|
||||
|
||||
const intl = useIntl();
|
||||
|
||||
const unfulfilledLines = order?.lines.filter(
|
||||
line => line.quantity !== line.quantityFulfilled
|
||||
);
|
||||
const fulfilledFulfillemnts =
|
||||
order?.fulfillments.filter(
|
||||
fulfillment => fulfillment.status === FulfillmentStatus.FULFILLED
|
||||
) || [];
|
||||
|
||||
return (
|
||||
<OrderRefundForm
|
||||
order={order}
|
||||
defaultType={defaultType}
|
||||
onSubmit={onSubmit}
|
||||
>
|
||||
{({ data, handlers, change, submit }) => (
|
||||
<Container>
|
||||
<AppHeader onBack={onBack}>
|
||||
{order?.number
|
||||
? intl.formatMessage(
|
||||
{
|
||||
defaultMessage: "Order #{orderNumber}",
|
||||
description: "page header with order number"
|
||||
},
|
||||
{
|
||||
orderNumber: order.number
|
||||
}
|
||||
)
|
||||
: intl.formatMessage({
|
||||
defaultMessage: "Order",
|
||||
description: "page header"
|
||||
})}
|
||||
</AppHeader>
|
||||
<PageHeader
|
||||
title={intl.formatMessage(
|
||||
{
|
||||
defaultMessage: "Order no. {orderNumber} - Refund",
|
||||
description: "page header"
|
||||
},
|
||||
{
|
||||
orderNumber: order?.number
|
||||
}
|
||||
)}
|
||||
/>
|
||||
<Grid>
|
||||
<div>
|
||||
<OrderRefund data={data} disabled={disabled} onChange={change} />
|
||||
{data.type === OrderRefundType.PRODUCTS && (
|
||||
<>
|
||||
{unfulfilledLines?.length > 0 && (
|
||||
<>
|
||||
<CardSpacer />
|
||||
<OrderRefundUnfulfilledProducts
|
||||
unfulfilledLines={unfulfilledLines}
|
||||
data={data}
|
||||
disabled={disabled}
|
||||
onRefundedProductQuantityChange={
|
||||
handlers.changeRefundedProductQuantity
|
||||
}
|
||||
onSetMaximalQuantities={
|
||||
handlers.setMaximalRefundedProductQuantities
|
||||
}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{renderCollection(fulfilledFulfillemnts, fulfillment => (
|
||||
<React.Fragment key={fulfillment?.id}>
|
||||
<CardSpacer />
|
||||
<OrderRefundFulfilledProducts
|
||||
fulfillment={fulfillment}
|
||||
data={data}
|
||||
disabled={disabled}
|
||||
orderNumber={order?.number}
|
||||
onRefundedProductQuantityChange={
|
||||
handlers.changeRefundedFulfilledProductQuantity
|
||||
}
|
||||
onSetMaximalQuantities={() =>
|
||||
handlers.setMaximalRefundedFulfilledProductQuantities(
|
||||
fulfillment?.id
|
||||
)
|
||||
}
|
||||
/>
|
||||
</React.Fragment>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
<OrderRefundAmount
|
||||
data={data}
|
||||
order={order}
|
||||
disabled={disabled}
|
||||
errors={errors}
|
||||
onChange={change}
|
||||
onRefund={submit}
|
||||
/>
|
||||
</div>
|
||||
</Grid>
|
||||
</Container>
|
||||
)}
|
||||
</OrderRefundForm>
|
||||
);
|
||||
};
|
||||
OrderRefundPage.displayName = "OrderRefundPage";
|
||||
export default OrderRefundPage;
|
181
src/orders/components/OrderRefundPage/fixtures.ts
Normal file
181
src/orders/components/OrderRefundPage/fixtures.ts
Normal file
|
@ -0,0 +1,181 @@
|
|||
/* eslint-disable sort-keys */
|
||||
|
||||
import { OrderRefundData_order } from "@saleor/orders/types/OrderRefundData";
|
||||
import { FulfillmentStatus } from "@saleor/types/globalTypes";
|
||||
|
||||
export const orderToRefund = (placeholder: string): OrderRefundData_order => ({
|
||||
__typename: "Order",
|
||||
id: "ifgdfuhdfdf",
|
||||
number: "22",
|
||||
total: {
|
||||
__typename: "TaxedMoney",
|
||||
gross: {
|
||||
__typename: "Money",
|
||||
amount: 744.38,
|
||||
currency: "USD"
|
||||
}
|
||||
},
|
||||
totalCaptured: {
|
||||
__typename: "Money",
|
||||
amount: 644.38,
|
||||
currency: "USD"
|
||||
},
|
||||
shippingPrice: {
|
||||
__typename: "TaxedMoney",
|
||||
gross: {
|
||||
__typename: "Money",
|
||||
amount: 20,
|
||||
currency: "USD"
|
||||
}
|
||||
},
|
||||
lines: [
|
||||
{
|
||||
__typename: "OrderLine",
|
||||
id: "diufhdsif",
|
||||
productName: "Milk",
|
||||
quantity: 19,
|
||||
quantityFulfilled: 3,
|
||||
thumbnail: {
|
||||
__typename: "Image",
|
||||
url: placeholder
|
||||
},
|
||||
unitPrice: {
|
||||
__typename: "TaxedMoney",
|
||||
gross: {
|
||||
__typename: "Money",
|
||||
amount: 26.02,
|
||||
currency: "USD"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
__typename: "OrderLine",
|
||||
id: "fdsfdfdsf",
|
||||
productName: "Coffee",
|
||||
quantity: 13,
|
||||
quantityFulfilled: 5,
|
||||
thumbnail: {
|
||||
__typename: "Image",
|
||||
url: placeholder
|
||||
},
|
||||
unitPrice: {
|
||||
__typename: "TaxedMoney",
|
||||
gross: {
|
||||
__typename: "Money",
|
||||
amount: 10,
|
||||
currency: "USD"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
fulfillments: [
|
||||
{
|
||||
__typename: "Fulfillment",
|
||||
id: "f12345qwertyu",
|
||||
status: FulfillmentStatus.FULFILLED,
|
||||
fulfillmentOrder: 1,
|
||||
lines: [
|
||||
{
|
||||
__typename: "FulfillmentLine",
|
||||
id: "fg3333fu66666",
|
||||
quantity: 1,
|
||||
orderLine: {
|
||||
__typename: "OrderLine",
|
||||
id: "diufhdsif",
|
||||
productName: "Milk",
|
||||
quantity: 1,
|
||||
thumbnail: {
|
||||
__typename: "Image",
|
||||
url: placeholder
|
||||
},
|
||||
unitPrice: {
|
||||
__typename: "TaxedMoney",
|
||||
gross: {
|
||||
__typename: "Money",
|
||||
amount: 26.02,
|
||||
currency: "USD"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
__typename: "FulfillmentLine",
|
||||
id: "fgytrytytu88977",
|
||||
quantity: 1,
|
||||
orderLine: {
|
||||
__typename: "OrderLine",
|
||||
id: "fdsfdfdsf",
|
||||
productName: "Coffee",
|
||||
quantity: 1,
|
||||
thumbnail: {
|
||||
__typename: "Image",
|
||||
url: placeholder
|
||||
},
|
||||
unitPrice: {
|
||||
__typename: "TaxedMoney",
|
||||
gross: {
|
||||
__typename: "Money",
|
||||
amount: 10,
|
||||
currency: "USD"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
__typename: "Fulfillment",
|
||||
id: "876543jhgfdfd",
|
||||
status: FulfillmentStatus.FULFILLED,
|
||||
fulfillmentOrder: 2,
|
||||
lines: [
|
||||
{
|
||||
__typename: "FulfillmentLine",
|
||||
id: "fgydgsyfu23456",
|
||||
quantity: 2,
|
||||
orderLine: {
|
||||
__typename: "OrderLine",
|
||||
id: "diufhdsif",
|
||||
productName: "Milk",
|
||||
quantity: 2,
|
||||
thumbnail: {
|
||||
__typename: "Image",
|
||||
url: placeholder
|
||||
},
|
||||
unitPrice: {
|
||||
__typename: "TaxedMoney",
|
||||
gross: {
|
||||
__typename: "Money",
|
||||
amount: 26.02,
|
||||
currency: "USD"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
__typename: "FulfillmentLine",
|
||||
id: "fgydgsyfu555444",
|
||||
quantity: 4,
|
||||
orderLine: {
|
||||
__typename: "OrderLine",
|
||||
id: "fdsfdfdsf",
|
||||
productName: "Coffee",
|
||||
quantity: 4,
|
||||
thumbnail: {
|
||||
__typename: "Image",
|
||||
url: placeholder
|
||||
},
|
||||
unitPrice: {
|
||||
__typename: "TaxedMoney",
|
||||
gross: {
|
||||
__typename: "Money",
|
||||
amount: 10,
|
||||
currency: "USD"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
});
|
202
src/orders/components/OrderRefundPage/form.tsx
Normal file
202
src/orders/components/OrderRefundPage/form.tsx
Normal file
|
@ -0,0 +1,202 @@
|
|||
import useForm, { FormChange, SubmitPromise } from "@saleor/hooks/useForm";
|
||||
import useFormset, {
|
||||
FormsetChange,
|
||||
FormsetData
|
||||
} from "@saleor/hooks/useFormset";
|
||||
import { OrderRefundData_order } from "@saleor/orders/types/OrderRefundData";
|
||||
import { FulfillmentStatus } from "@saleor/types/globalTypes";
|
||||
import handleFormSubmit from "@saleor/utils/handlers/handleFormSubmit";
|
||||
import React from "react";
|
||||
|
||||
export enum OrderRefundType {
|
||||
MISCELLANEOUS = "miscellaneous",
|
||||
PRODUCTS = "products"
|
||||
}
|
||||
export enum OrderRefundAmountCalculationMode {
|
||||
AUTOMATIC = "automatic",
|
||||
MANUAL = "manual"
|
||||
}
|
||||
|
||||
export interface OrderRefundData {
|
||||
amount: number | string;
|
||||
type: OrderRefundType;
|
||||
refundShipmentCosts: boolean;
|
||||
amountCalculationMode: OrderRefundAmountCalculationMode;
|
||||
}
|
||||
|
||||
export interface OrderRefundHandlers {
|
||||
changeRefundedProductQuantity: FormsetChange<string>;
|
||||
setMaximalRefundedProductQuantities: () => void;
|
||||
changeRefundedFulfilledProductQuantity: FormsetChange<string>;
|
||||
setMaximalRefundedFulfilledProductQuantities: (fulfillmentId: string) => void;
|
||||
}
|
||||
|
||||
export interface OrderRefundFormData extends OrderRefundData {
|
||||
refundedProductQuantities: FormsetData<null, string>;
|
||||
refundedFulfilledProductQuantities: FormsetData<null, string>;
|
||||
}
|
||||
|
||||
export type OrderRefundSubmitData = OrderRefundFormData;
|
||||
|
||||
export interface UseOrderRefundFormResult {
|
||||
change: FormChange;
|
||||
data: OrderRefundFormData;
|
||||
disabled: boolean;
|
||||
handlers: OrderRefundHandlers;
|
||||
hasChanged: boolean;
|
||||
submit: () => Promise<boolean>;
|
||||
}
|
||||
|
||||
interface OrderRefundFormProps {
|
||||
children: (props: UseOrderRefundFormResult) => React.ReactNode;
|
||||
order: OrderRefundData_order;
|
||||
defaultType: OrderRefundType;
|
||||
onSubmit: (data: OrderRefundSubmitData) => SubmitPromise;
|
||||
}
|
||||
|
||||
function getOrderRefundPageFormData(
|
||||
defaultType: OrderRefundType
|
||||
): OrderRefundData {
|
||||
return {
|
||||
amount: undefined,
|
||||
amountCalculationMode: OrderRefundAmountCalculationMode.AUTOMATIC,
|
||||
refundShipmentCosts: false,
|
||||
type: defaultType
|
||||
};
|
||||
}
|
||||
|
||||
function useOrderRefundForm(
|
||||
order: OrderRefundData_order,
|
||||
defaultType: OrderRefundType,
|
||||
onSubmit: (data: OrderRefundSubmitData) => SubmitPromise
|
||||
): UseOrderRefundFormResult {
|
||||
const [changed, setChanged] = React.useState(false);
|
||||
const triggerChange = () => setChanged(true);
|
||||
|
||||
const form = useForm(getOrderRefundPageFormData(defaultType));
|
||||
const refundedProductQuantities = useFormset<null, string>(
|
||||
order?.lines
|
||||
.filter(line => line.quantityFulfilled !== line.quantity)
|
||||
.map(line => ({
|
||||
data: null,
|
||||
id: line.id,
|
||||
label: null,
|
||||
value: "0"
|
||||
}))
|
||||
);
|
||||
const refundedFulfilledProductQuantities = useFormset<null, string>(
|
||||
order?.fulfillments
|
||||
.filter(fulfillment => fulfillment.status === FulfillmentStatus.FULFILLED)
|
||||
.reduce(
|
||||
(linesQty, fulfillemnt) =>
|
||||
linesQty.concat(
|
||||
fulfillemnt.lines.map(fulfillmentLine => ({
|
||||
data: null,
|
||||
id: fulfillmentLine.id,
|
||||
label: null,
|
||||
value: "0"
|
||||
}))
|
||||
),
|
||||
[]
|
||||
)
|
||||
);
|
||||
|
||||
const handleChange: FormChange = (event, cb) => {
|
||||
form.change(event, cb);
|
||||
triggerChange();
|
||||
};
|
||||
const handleRefundedProductQuantityChange: FormsetChange<string> = (
|
||||
id,
|
||||
value
|
||||
) => {
|
||||
triggerChange();
|
||||
refundedProductQuantities.change(id, value);
|
||||
};
|
||||
const handleRefundedFulFilledProductQuantityChange = (
|
||||
id: string,
|
||||
value: string
|
||||
) => {
|
||||
triggerChange();
|
||||
refundedFulfilledProductQuantities.change(id, value);
|
||||
};
|
||||
const handleMaximalRefundedProductQuantitiesSet = () => {
|
||||
const newQuantities: FormsetData<
|
||||
null,
|
||||
string
|
||||
> = refundedProductQuantities.data.map(selectedLine => {
|
||||
const line = order.lines.find(line => line.id === selectedLine.id);
|
||||
|
||||
return {
|
||||
data: null,
|
||||
id: line.id,
|
||||
label: null,
|
||||
value: (line.quantity - line.quantityFulfilled).toString()
|
||||
};
|
||||
});
|
||||
refundedProductQuantities.set(newQuantities);
|
||||
triggerChange();
|
||||
};
|
||||
const handleMaximalRefundedFulfilledProductQuantitiesSet = (
|
||||
fulfillmentId: string
|
||||
) => {
|
||||
const fulfillment = order.fulfillments.find(
|
||||
fulfillment => fulfillment.id === fulfillmentId
|
||||
);
|
||||
const newQuantities: FormsetData<
|
||||
null,
|
||||
string
|
||||
> = refundedFulfilledProductQuantities.data.map(selectedLine => {
|
||||
const line = fulfillment.lines.find(line => line.id === selectedLine.id);
|
||||
|
||||
if (line) {
|
||||
return {
|
||||
data: null,
|
||||
id: line.id,
|
||||
label: null,
|
||||
value: line.quantity.toString()
|
||||
};
|
||||
}
|
||||
return selectedLine;
|
||||
});
|
||||
refundedFulfilledProductQuantities.set(newQuantities);
|
||||
triggerChange();
|
||||
};
|
||||
|
||||
const data: OrderRefundFormData = {
|
||||
...form.data,
|
||||
refundedFulfilledProductQuantities: refundedFulfilledProductQuantities.data,
|
||||
refundedProductQuantities: refundedProductQuantities.data
|
||||
};
|
||||
|
||||
const submit = () => handleFormSubmit(data, onSubmit, setChanged);
|
||||
|
||||
const disabled = !order;
|
||||
|
||||
return {
|
||||
change: handleChange,
|
||||
data,
|
||||
disabled,
|
||||
handlers: {
|
||||
changeRefundedFulfilledProductQuantity: handleRefundedFulFilledProductQuantityChange,
|
||||
changeRefundedProductQuantity: handleRefundedProductQuantityChange,
|
||||
setMaximalRefundedFulfilledProductQuantities: handleMaximalRefundedFulfilledProductQuantitiesSet,
|
||||
setMaximalRefundedProductQuantities: handleMaximalRefundedProductQuantitiesSet
|
||||
},
|
||||
hasChanged: changed,
|
||||
submit
|
||||
};
|
||||
}
|
||||
|
||||
const OrderRefundForm: React.FC<OrderRefundFormProps> = ({
|
||||
children,
|
||||
order,
|
||||
defaultType,
|
||||
onSubmit
|
||||
}) => {
|
||||
const props = useOrderRefundForm(order, defaultType, onSubmit);
|
||||
|
||||
return <form onSubmit={props.submit}>{children(props)}</form>;
|
||||
};
|
||||
|
||||
OrderRefundForm.displayName = "OrderRefundForm";
|
||||
export default OrderRefundForm;
|
2
src/orders/components/OrderRefundPage/index.ts
Normal file
2
src/orders/components/OrderRefundPage/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
|||
export * from "./OrderRefundPage";
|
||||
export { default } from "./OrderRefundPage";
|
|
@ -0,0 +1,237 @@
|
|||
import { makeStyles } from "@material-ui/core";
|
||||
import Button from "@material-ui/core/Button";
|
||||
import Card from "@material-ui/core/Card";
|
||||
import CardContent from "@material-ui/core/CardContent";
|
||||
import Table from "@material-ui/core/Table";
|
||||
import TableBody from "@material-ui/core/TableBody";
|
||||
import TableCell from "@material-ui/core/TableCell";
|
||||
import TableHead from "@material-ui/core/TableHead";
|
||||
import TableRow from "@material-ui/core/TableRow";
|
||||
import TextField from "@material-ui/core/TextField";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import { CSSProperties } from "@material-ui/styles";
|
||||
import CardTitle from "@saleor/components/CardTitle";
|
||||
import Money from "@saleor/components/Money";
|
||||
import Skeleton from "@saleor/components/Skeleton";
|
||||
import TableCellAvatar from "@saleor/components/TableCellAvatar";
|
||||
import { FormsetChange } from "@saleor/hooks/useFormset";
|
||||
import { renderCollection } from "@saleor/misc";
|
||||
import { OrderRefundData_order_lines } from "@saleor/orders/types/OrderRefundData";
|
||||
import React from "react";
|
||||
import { FormattedMessage, useIntl } from "react-intl";
|
||||
|
||||
import { OrderRefundFormData } from "../OrderRefundPage/form";
|
||||
|
||||
const useStyles = makeStyles(
|
||||
theme => {
|
||||
const inputPadding: CSSProperties = {
|
||||
paddingBottom: theme.spacing(2),
|
||||
paddingTop: theme.spacing(2)
|
||||
};
|
||||
|
||||
return {
|
||||
cartContent: {
|
||||
paddingBottom: 0,
|
||||
paddingTop: 0
|
||||
},
|
||||
colQuantity: {
|
||||
textAlign: "right",
|
||||
width: 210
|
||||
},
|
||||
notice: {
|
||||
marginBottom: theme.spacing(1),
|
||||
marginTop: theme.spacing(2)
|
||||
},
|
||||
quantityInnerInput: {
|
||||
...inputPadding
|
||||
},
|
||||
quantityInnerInputNoRemaining: {
|
||||
paddingRight: 0
|
||||
},
|
||||
remainingQuantity: {
|
||||
...inputPadding,
|
||||
color: theme.palette.text.secondary,
|
||||
whiteSpace: "nowrap"
|
||||
},
|
||||
setMaximalQuantityButton: {
|
||||
marginTop: theme.spacing(1)
|
||||
}
|
||||
};
|
||||
},
|
||||
{ name: "OrderRefundUnfulfilledProducts" }
|
||||
);
|
||||
|
||||
interface OrderRefundUnfulfilledProductsProps {
|
||||
unfulfilledLines: OrderRefundData_order_lines[];
|
||||
data: OrderRefundFormData;
|
||||
disabled: boolean;
|
||||
onRefundedProductQuantityChange: FormsetChange<string>;
|
||||
onSetMaximalQuantities: () => void;
|
||||
}
|
||||
|
||||
const OrderRefundUnfulfilledProducts: React.FC<OrderRefundUnfulfilledProductsProps> = props => {
|
||||
const {
|
||||
unfulfilledLines,
|
||||
data,
|
||||
disabled,
|
||||
onRefundedProductQuantityChange,
|
||||
onSetMaximalQuantities
|
||||
} = props;
|
||||
const classes = useStyles(props);
|
||||
const intl = useIntl();
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardTitle
|
||||
title={intl.formatMessage({
|
||||
defaultMessage: "Unfulfilled Products",
|
||||
description: "section header"
|
||||
})}
|
||||
/>
|
||||
<CardContent className={classes.cartContent}>
|
||||
<Typography
|
||||
variant="caption"
|
||||
color="textSecondary"
|
||||
className={classes.notice}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Unfulfilled products will be restocked"
|
||||
description="section notice"
|
||||
/>
|
||||
</Typography>
|
||||
<Button
|
||||
className={classes.setMaximalQuantityButton}
|
||||
color="primary"
|
||||
onClick={onSetMaximalQuantities}
|
||||
data-test="setMaximalQuantityUnfulfilledButton"
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Set maximal quantities"
|
||||
description="button"
|
||||
/>
|
||||
</Button>
|
||||
</CardContent>
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell>
|
||||
<FormattedMessage
|
||||
defaultMessage="Product"
|
||||
description="tabel column header"
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<FormattedMessage
|
||||
defaultMessage="Price"
|
||||
description="tabel column header"
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<FormattedMessage
|
||||
defaultMessage="Refunded Qty"
|
||||
description="tabel column header"
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<FormattedMessage
|
||||
defaultMessage="Total"
|
||||
description="tabel column header"
|
||||
/>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{renderCollection(
|
||||
unfulfilledLines,
|
||||
line => {
|
||||
const selectedLineQuantity = data.refundedProductQuantities.find(
|
||||
refundedLine => refundedLine.id === line.id
|
||||
);
|
||||
const lineQuantity = line?.quantity - line?.quantityFulfilled;
|
||||
const isError =
|
||||
Number(selectedLineQuantity?.value) > lineQuantity ||
|
||||
Number(selectedLineQuantity?.value) < 0;
|
||||
|
||||
return (
|
||||
<TableRow key={line?.id}>
|
||||
<TableCellAvatar thumbnail={line?.thumbnail?.url}>
|
||||
{line?.productName ? line?.productName : <Skeleton />}
|
||||
</TableCellAvatar>
|
||||
<TableCell>
|
||||
{line?.unitPrice ? (
|
||||
<Money money={line?.unitPrice.gross} />
|
||||
) : (
|
||||
<Skeleton />
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell className={classes.colQuantity}>
|
||||
{lineQuantity || lineQuantity === 0 ? (
|
||||
<TextField
|
||||
disabled={disabled}
|
||||
type="number"
|
||||
inputProps={{
|
||||
className: classes.quantityInnerInput,
|
||||
"data-test": "quantityInput",
|
||||
"data-test-id": line?.id,
|
||||
max: lineQuantity.toString(),
|
||||
min: 0,
|
||||
style: { textAlign: "right" }
|
||||
}}
|
||||
fullWidth
|
||||
value={selectedLineQuantity?.value}
|
||||
onChange={event =>
|
||||
onRefundedProductQuantityChange(
|
||||
line.id,
|
||||
event.target.value
|
||||
)
|
||||
}
|
||||
InputProps={{
|
||||
endAdornment: lineQuantity && (
|
||||
<div className={classes.remainingQuantity}>
|
||||
/ {lineQuantity}
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
error={isError}
|
||||
helperText={
|
||||
isError &&
|
||||
intl.formatMessage({
|
||||
defaultMessage: "Improper value",
|
||||
description: "error message"
|
||||
})
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
<Skeleton />
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{(line?.unitPrice.gross && (
|
||||
<Money
|
||||
money={{
|
||||
...line.unitPrice.gross,
|
||||
amount:
|
||||
(line.unitPrice.gross.amount ?? 0) *
|
||||
Number(selectedLineQuantity?.value)
|
||||
}}
|
||||
/>
|
||||
)) || <Skeleton />}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
},
|
||||
() => (
|
||||
<TableRow>
|
||||
<TableCell colSpan={4}>
|
||||
<FormattedMessage defaultMessage="No products found" />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
OrderRefundUnfulfilledProducts.displayName = "OrderRefundUnfulfilledProducts";
|
||||
export default OrderRefundUnfulfilledProducts;
|
|
@ -0,0 +1,2 @@
|
|||
export * from "./OrderRefundUnfulfilledProducts";
|
||||
export { default } from "./OrderRefundUnfulfilledProducts";
|
|
@ -17,7 +17,6 @@ import {
|
|||
TypedOrderLinesAddMutation,
|
||||
TypedOrderLineUpdateMutation,
|
||||
TypedOrderMarkAsPaidMutation,
|
||||
TypedOrderRefundMutation,
|
||||
TypedOrderShippingMethodUpdateMutation,
|
||||
TypedOrderUpdateMutation,
|
||||
TypedOrderVoidMutation
|
||||
|
@ -66,7 +65,6 @@ import {
|
|||
OrderMarkAsPaid,
|
||||
OrderMarkAsPaidVariables
|
||||
} from "../types/OrderMarkAsPaid";
|
||||
import { OrderRefund, OrderRefundVariables } from "../types/OrderRefund";
|
||||
import {
|
||||
OrderShippingMethodUpdate,
|
||||
OrderShippingMethodUpdateVariables
|
||||
|
@ -97,10 +95,6 @@ interface OrderOperationsProps {
|
|||
OrderCapture,
|
||||
OrderCaptureVariables
|
||||
>;
|
||||
orderPaymentRefund: PartialMutationProviderOutput<
|
||||
OrderRefund,
|
||||
OrderRefundVariables
|
||||
>;
|
||||
orderPaymentMarkAsPaid: PartialMutationProviderOutput<
|
||||
OrderMarkAsPaid,
|
||||
OrderMarkAsPaidVariables
|
||||
|
@ -154,7 +148,6 @@ interface OrderOperationsProps {
|
|||
onOrderMarkAsPaid: (data: OrderMarkAsPaid) => void;
|
||||
onNoteAdd: (data: OrderAddNote) => void;
|
||||
onPaymentCapture: (data: OrderCapture) => void;
|
||||
onPaymentRefund: (data: OrderRefund) => void;
|
||||
onUpdate: (data: OrderUpdate) => void;
|
||||
onDraftCancel: (data: OrderDraftCancel) => void;
|
||||
onDraftFinalize: (data: OrderDraftFinalize) => void;
|
||||
|
@ -177,7 +170,6 @@ const OrderOperations: React.FC<OrderOperationsProps> = ({
|
|||
onOrderLineUpdate,
|
||||
onOrderVoid,
|
||||
onPaymentCapture,
|
||||
onPaymentRefund,
|
||||
onShippingMethodUpdate,
|
||||
onUpdate,
|
||||
onDraftCancel,
|
||||
|
@ -194,8 +186,6 @@ const OrderOperations: React.FC<OrderOperationsProps> = ({
|
|||
{(...orderCancel) => (
|
||||
<TypedOrderCaptureMutation onCompleted={onPaymentCapture}>
|
||||
{(...paymentCapture) => (
|
||||
<TypedOrderRefundMutation onCompleted={onPaymentRefund}>
|
||||
{(...paymentRefund) => (
|
||||
<TypedOrderAddNoteMutation onCompleted={onNoteAdd}>
|
||||
{(...addNote) => (
|
||||
<TypedOrderUpdateMutation onCompleted={onUpdate}>
|
||||
|
@ -231,9 +221,7 @@ const OrderOperations: React.FC<OrderOperationsProps> = ({
|
|||
onOrderFulfillmentUpdate
|
||||
}
|
||||
>
|
||||
{(
|
||||
...updateTrackingNumber
|
||||
) => (
|
||||
{(...updateTrackingNumber) => (
|
||||
<TypedOrderDraftFinalizeMutation
|
||||
onCompleted={
|
||||
onDraftFinalize
|
||||
|
@ -245,9 +233,7 @@ const OrderOperations: React.FC<OrderOperationsProps> = ({
|
|||
onDraftCancel
|
||||
}
|
||||
>
|
||||
{(
|
||||
...cancelDraft
|
||||
) => (
|
||||
{(...cancelDraft) => (
|
||||
<TypedOrderMarkAsPaidMutation
|
||||
onCompleted={
|
||||
onOrderMarkAsPaid
|
||||
|
@ -272,8 +258,7 @@ const OrderOperations: React.FC<OrderOperationsProps> = ({
|
|||
{(
|
||||
...invoiceEmailSend
|
||||
) =>
|
||||
children(
|
||||
{
|
||||
children({
|
||||
orderAddNote: getMutationProviderData(
|
||||
...addNote
|
||||
),
|
||||
|
@ -316,9 +301,6 @@ const OrderOperations: React.FC<OrderOperationsProps> = ({
|
|||
orderPaymentMarkAsPaid: getMutationProviderData(
|
||||
...markAsPaid
|
||||
),
|
||||
orderPaymentRefund: getMutationProviderData(
|
||||
...paymentRefund
|
||||
),
|
||||
orderShippingMethodUpdate: getMutationProviderData(
|
||||
...updateShippingMethod
|
||||
),
|
||||
|
@ -328,8 +310,7 @@ const OrderOperations: React.FC<OrderOperationsProps> = ({
|
|||
orderVoid: getMutationProviderData(
|
||||
...orderVoid
|
||||
)
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
</TypedInvoiceEmailSendMutation>
|
||||
)}
|
||||
|
@ -359,8 +340,6 @@ const OrderOperations: React.FC<OrderOperationsProps> = ({
|
|||
)}
|
||||
</TypedOrderAddNoteMutation>
|
||||
)}
|
||||
</TypedOrderRefundMutation>
|
||||
)}
|
||||
</TypedOrderCaptureMutation>
|
||||
)}
|
||||
</TypedOrderCancelMutation>
|
||||
|
|
|
@ -831,8 +831,10 @@ export const order = (placeholder: string): OrderDetails_order => ({
|
|||
emailType: null,
|
||||
id: "T3JkZXJFdmVudDoyMQ==",
|
||||
invoiceNumber: null,
|
||||
lines: [],
|
||||
message: null,
|
||||
quantity: 1,
|
||||
shippingCostsIncluded: false,
|
||||
transactionReference: "123",
|
||||
type: OrderEventsEnum.FULFILLMENT_FULFILLED_ITEMS,
|
||||
user: {
|
||||
|
@ -841,6 +843,47 @@ export const order = (placeholder: string): OrderDetails_order => ({
|
|||
id: "QWRkcmVzczoxNQ=="
|
||||
}
|
||||
},
|
||||
{
|
||||
__typename: "OrderEvent",
|
||||
amount: null,
|
||||
date: "2018-09-17T13:22:24.376193+00:00",
|
||||
email: null,
|
||||
emailType: null,
|
||||
id: "UYgDNUnnfyiuyimuhd==",
|
||||
invoiceNumber: null,
|
||||
lines: [
|
||||
{
|
||||
__typename: "OrderEventOrderLineObject",
|
||||
orderLine: {
|
||||
__typename: "OrderLine",
|
||||
id: "h47gfncfgwegfehfhj",
|
||||
productName: "Milk",
|
||||
variantName: "Cow's milk"
|
||||
},
|
||||
quantity: 4
|
||||
},
|
||||
{
|
||||
__typename: "OrderEventOrderLineObject",
|
||||
orderLine: {
|
||||
__typename: "OrderLine",
|
||||
id: "7846f857t4t84y8fgh",
|
||||
productName: "Milk",
|
||||
variantName: "Goat's milk"
|
||||
},
|
||||
quantity: 4
|
||||
}
|
||||
],
|
||||
message: null,
|
||||
quantity: 1,
|
||||
shippingCostsIncluded: true,
|
||||
transactionReference: "123",
|
||||
type: OrderEventsEnum.FULFILLMENT_REFUNDED,
|
||||
user: {
|
||||
__typename: "User",
|
||||
email: "admin@example.com",
|
||||
id: "QWRkcmVzczoxNQ=="
|
||||
}
|
||||
},
|
||||
{
|
||||
__typename: "OrderEvent",
|
||||
amount: null,
|
||||
|
@ -849,8 +892,10 @@ export const order = (placeholder: string): OrderDetails_order => ({
|
|||
emailType: null,
|
||||
id: "T3JkZXJFdmVudDo0",
|
||||
invoiceNumber: null,
|
||||
lines: [],
|
||||
message: "This is note",
|
||||
quantity: null,
|
||||
shippingCostsIncluded: false,
|
||||
transactionReference: "124",
|
||||
type: OrderEventsEnum.NOTE_ADDED,
|
||||
user: null
|
||||
|
@ -863,8 +908,10 @@ export const order = (placeholder: string): OrderDetails_order => ({
|
|||
emailType: null,
|
||||
id: "T3JkZXJFdmVudDo1",
|
||||
invoiceNumber: null,
|
||||
lines: [],
|
||||
message: "This is note",
|
||||
quantity: null,
|
||||
shippingCostsIncluded: false,
|
||||
transactionReference: "125",
|
||||
type: OrderEventsEnum.NOTE_ADDED,
|
||||
user: null
|
||||
|
@ -877,8 +924,10 @@ export const order = (placeholder: string): OrderDetails_order => ({
|
|||
emailType: null,
|
||||
id: "T3JkZXJFdmVudDo2",
|
||||
invoiceNumber: null,
|
||||
lines: [],
|
||||
message: "Note from external service",
|
||||
quantity: null,
|
||||
shippingCostsIncluded: false,
|
||||
transactionReference: "126",
|
||||
type: OrderEventsEnum.EXTERNAL_SERVICE_NOTIFICATION,
|
||||
user: null
|
||||
|
@ -891,8 +940,10 @@ export const order = (placeholder: string): OrderDetails_order => ({
|
|||
emailType: OrderEventsEmailsEnum.ORDER_CANCEL,
|
||||
id: "T3JkZXJFdmVudDo3",
|
||||
invoiceNumber: null,
|
||||
lines: [],
|
||||
message: null,
|
||||
quantity: null,
|
||||
shippingCostsIncluded: false,
|
||||
transactionReference: "127",
|
||||
type: OrderEventsEnum.EMAIL_SENT,
|
||||
user: null
|
||||
|
@ -905,8 +956,10 @@ export const order = (placeholder: string): OrderDetails_order => ({
|
|||
emailType: OrderEventsEmailsEnum.ORDER_REFUND,
|
||||
id: "T3JkZXJFdmVudDo4",
|
||||
invoiceNumber: null,
|
||||
lines: [],
|
||||
message: null,
|
||||
quantity: null,
|
||||
shippingCostsIncluded: false,
|
||||
transactionReference: "128",
|
||||
type: OrderEventsEnum.EMAIL_SENT,
|
||||
user: null
|
||||
|
@ -919,8 +972,10 @@ export const order = (placeholder: string): OrderDetails_order => ({
|
|||
emailType: null,
|
||||
id: "T3JkZXJFdmVudDo5",
|
||||
invoiceNumber: null,
|
||||
lines: [],
|
||||
message: null,
|
||||
quantity: null,
|
||||
shippingCostsIncluded: false,
|
||||
transactionReference: "129",
|
||||
type: OrderEventsEnum.PAYMENT_AUTHORIZED,
|
||||
user: null
|
||||
|
|
|
@ -15,6 +15,7 @@ import {
|
|||
OrderListUrlQueryParams,
|
||||
OrderListUrlSortField,
|
||||
orderPath,
|
||||
orderRefundPath,
|
||||
orderSettingsPath,
|
||||
OrderUrlQueryParams
|
||||
} from "./urls";
|
||||
|
@ -22,6 +23,7 @@ import OrderDetailsComponent from "./views/OrderDetails";
|
|||
import OrderDraftListComponent from "./views/OrderDraftList";
|
||||
import OrderFulfillComponent from "./views/OrderFulfill";
|
||||
import OrderListComponent from "./views/OrderList";
|
||||
import OrderRefundComponent from "./views/OrderRefund";
|
||||
import OrderSettings from "./views/OrderSettings";
|
||||
|
||||
const OrderList: React.FC<RouteComponentProps<any>> = ({ location }) => {
|
||||
|
@ -65,6 +67,10 @@ const OrderFulfill: React.FC<RouteComponentProps<any>> = ({ match }) => (
|
|||
<OrderFulfillComponent orderId={decodeURIComponent(match.params.id)} />
|
||||
);
|
||||
|
||||
const OrderRefund: React.FC<RouteComponentProps<any>> = ({ match }) => (
|
||||
<OrderRefundComponent orderId={decodeURIComponent(match.params.id)} />
|
||||
);
|
||||
|
||||
const Component = () => {
|
||||
const intl = useIntl();
|
||||
|
||||
|
@ -76,6 +82,7 @@ const Component = () => {
|
|||
<Route exact path={orderDraftListPath} component={OrderDraftList} />
|
||||
<Route exact path={orderListPath} component={OrderList} />
|
||||
<Route path={orderFulfillPath(":id")} component={OrderFulfill} />
|
||||
<Route path={orderRefundPath(":id")} component={OrderRefund} />
|
||||
<Route path={orderPath(":id")} component={OrderDetails} />
|
||||
</Switch>
|
||||
</>
|
||||
|
|
|
@ -7,6 +7,7 @@ import {
|
|||
fragmentOrderDetails,
|
||||
fragmentOrderEvent,
|
||||
fragmentOrderSettings,
|
||||
fulfillmentFragment,
|
||||
invoiceFragment
|
||||
} from "@saleor/fragments/orders";
|
||||
import makeMutation from "@saleor/hooks/makeMutation";
|
||||
|
@ -50,6 +51,10 @@ import {
|
|||
OrderFulfillmentCancel,
|
||||
OrderFulfillmentCancelVariables
|
||||
} from "./types/OrderFulfillmentCancel";
|
||||
import {
|
||||
OrderFulfillmentRefundProducts,
|
||||
OrderFulfillmentRefundProductsVariables
|
||||
} from "./types/OrderFulfillmentRefundProducts";
|
||||
import {
|
||||
OrderFulfillmentUpdateTracking,
|
||||
OrderFulfillmentUpdateTrackingVariables
|
||||
|
@ -186,11 +191,37 @@ const orderRefundMutation = gql`
|
|||
}
|
||||
}
|
||||
`;
|
||||
export const TypedOrderRefundMutation = TypedMutation<
|
||||
export const useOrderRefundMutation = makeMutation<
|
||||
OrderRefund,
|
||||
OrderRefundVariables
|
||||
>(orderRefundMutation);
|
||||
|
||||
const orderFulfillmentRefundProductsMutation = gql`
|
||||
${fragmentOrderDetails}
|
||||
${fulfillmentFragment}
|
||||
${orderErrorFragment}
|
||||
mutation OrderFulfillmentRefundProducts(
|
||||
$input: OrderRefundProductsInput!
|
||||
$order: ID!
|
||||
) {
|
||||
orderFulfillmentRefundProducts(input: $input, order: $order) {
|
||||
errors: orderErrors {
|
||||
...OrderErrorFragment
|
||||
}
|
||||
fulfillment {
|
||||
...FulfillmentFragment
|
||||
}
|
||||
order {
|
||||
...OrderDetailsFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
export const useOrderFulfillmentRefundProductsMutation = makeMutation<
|
||||
OrderFulfillmentRefundProducts,
|
||||
OrderFulfillmentRefundProductsVariables
|
||||
>(orderFulfillmentRefundProductsMutation);
|
||||
|
||||
const orderVoidMutation = gql`
|
||||
${fragmentOrderDetails}
|
||||
${orderErrorFragment}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import { fragmentAddress } from "@saleor/fragments/address";
|
||||
import {
|
||||
fragmentOrderDetails,
|
||||
fragmentOrderSettings
|
||||
fragmentOrderSettings,
|
||||
fragmentRefundOrderLine
|
||||
} from "@saleor/fragments/orders";
|
||||
import { fragmentMoney } from "@saleor/fragments/products";
|
||||
import makeQuery from "@saleor/hooks/makeQuery";
|
||||
import makeTopLevelSearch from "@saleor/hooks/makeTopLevelSearch";
|
||||
import gql from "graphql-tag";
|
||||
|
@ -18,6 +20,10 @@ import {
|
|||
OrderFulfillDataVariables
|
||||
} from "./types/OrderFulfillData";
|
||||
import { OrderList, OrderListVariables } from "./types/OrderList";
|
||||
import {
|
||||
OrderRefundData,
|
||||
OrderRefundDataVariables
|
||||
} from "./types/OrderRefundData";
|
||||
import { OrderSettings } from "./types/OrderSettings";
|
||||
import {
|
||||
SearchOrderVariant as SearchOrderVariantType,
|
||||
|
@ -254,3 +260,47 @@ export const orderSettingsQuery = gql`
|
|||
export const useOrderSettingsQuery = makeQuery<OrderSettings, never>(
|
||||
orderSettingsQuery
|
||||
);
|
||||
|
||||
const orderRefundData = gql`
|
||||
${fragmentMoney}
|
||||
${fragmentRefundOrderLine}
|
||||
query OrderRefundData($orderId: ID!) {
|
||||
order(id: $orderId) {
|
||||
id
|
||||
number
|
||||
total {
|
||||
gross {
|
||||
...Money
|
||||
}
|
||||
}
|
||||
totalCaptured {
|
||||
...Money
|
||||
}
|
||||
shippingPrice {
|
||||
gross {
|
||||
...Money
|
||||
}
|
||||
}
|
||||
lines {
|
||||
...RefundOrderLineFragment
|
||||
quantityFulfilled
|
||||
}
|
||||
fulfillments {
|
||||
id
|
||||
status
|
||||
fulfillmentOrder
|
||||
lines {
|
||||
id
|
||||
quantity
|
||||
orderLine {
|
||||
...RefundOrderLineFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
export const useOrderRefundData = makeQuery<
|
||||
OrderRefundData,
|
||||
OrderRefundDataVariables
|
||||
>(orderRefundData);
|
||||
|
|
|
@ -56,10 +56,24 @@ export interface FulfillOrder_orderFulfill_order_events_user {
|
|||
email: string;
|
||||
}
|
||||
|
||||
export interface FulfillOrder_orderFulfill_order_events_lines_orderLine {
|
||||
__typename: "OrderLine";
|
||||
id: string;
|
||||
productName: string;
|
||||
variantName: string;
|
||||
}
|
||||
|
||||
export interface FulfillOrder_orderFulfill_order_events_lines {
|
||||
__typename: "OrderEventOrderLineObject";
|
||||
quantity: number | null;
|
||||
orderLine: FulfillOrder_orderFulfill_order_events_lines_orderLine | null;
|
||||
}
|
||||
|
||||
export interface FulfillOrder_orderFulfill_order_events {
|
||||
__typename: "OrderEvent";
|
||||
id: string;
|
||||
amount: number | null;
|
||||
shippingCostsIncluded: boolean | null;
|
||||
date: any | null;
|
||||
email: string | null;
|
||||
emailType: OrderEventsEmailsEnum | null;
|
||||
|
@ -69,6 +83,7 @@ export interface FulfillOrder_orderFulfill_order_events {
|
|||
transactionReference: string | null;
|
||||
type: OrderEventsEnum | null;
|
||||
user: FulfillOrder_orderFulfill_order_events_user | null;
|
||||
lines: (FulfillOrder_orderFulfill_order_events_lines | null)[] | null;
|
||||
}
|
||||
|
||||
export interface FulfillOrder_orderFulfill_order_fulfillments_lines_orderLine_variant {
|
||||
|
|
|
@ -20,10 +20,24 @@ export interface OrderAddNote_orderAddNote_order_events_user {
|
|||
email: string;
|
||||
}
|
||||
|
||||
export interface OrderAddNote_orderAddNote_order_events_lines_orderLine {
|
||||
__typename: "OrderLine";
|
||||
id: string;
|
||||
productName: string;
|
||||
variantName: string;
|
||||
}
|
||||
|
||||
export interface OrderAddNote_orderAddNote_order_events_lines {
|
||||
__typename: "OrderEventOrderLineObject";
|
||||
quantity: number | null;
|
||||
orderLine: OrderAddNote_orderAddNote_order_events_lines_orderLine | null;
|
||||
}
|
||||
|
||||
export interface OrderAddNote_orderAddNote_order_events {
|
||||
__typename: "OrderEvent";
|
||||
id: string;
|
||||
amount: number | null;
|
||||
shippingCostsIncluded: boolean | null;
|
||||
date: any | null;
|
||||
email: string | null;
|
||||
emailType: OrderEventsEmailsEnum | null;
|
||||
|
@ -33,6 +47,7 @@ export interface OrderAddNote_orderAddNote_order_events {
|
|||
transactionReference: string | null;
|
||||
type: OrderEventsEnum | null;
|
||||
user: OrderAddNote_orderAddNote_order_events_user | null;
|
||||
lines: (OrderAddNote_orderAddNote_order_events_lines | null)[] | null;
|
||||
}
|
||||
|
||||
export interface OrderAddNote_orderAddNote_order {
|
||||
|
|
|
@ -54,10 +54,24 @@ export interface OrderCancel_orderCancel_order_events_user {
|
|||
email: string;
|
||||
}
|
||||
|
||||
export interface OrderCancel_orderCancel_order_events_lines_orderLine {
|
||||
__typename: "OrderLine";
|
||||
id: string;
|
||||
productName: string;
|
||||
variantName: string;
|
||||
}
|
||||
|
||||
export interface OrderCancel_orderCancel_order_events_lines {
|
||||
__typename: "OrderEventOrderLineObject";
|
||||
quantity: number | null;
|
||||
orderLine: OrderCancel_orderCancel_order_events_lines_orderLine | null;
|
||||
}
|
||||
|
||||
export interface OrderCancel_orderCancel_order_events {
|
||||
__typename: "OrderEvent";
|
||||
id: string;
|
||||
amount: number | null;
|
||||
shippingCostsIncluded: boolean | null;
|
||||
date: any | null;
|
||||
email: string | null;
|
||||
emailType: OrderEventsEmailsEnum | null;
|
||||
|
@ -67,6 +81,7 @@ export interface OrderCancel_orderCancel_order_events {
|
|||
transactionReference: string | null;
|
||||
type: OrderEventsEnum | null;
|
||||
user: OrderCancel_orderCancel_order_events_user | null;
|
||||
lines: (OrderCancel_orderCancel_order_events_lines | null)[] | null;
|
||||
}
|
||||
|
||||
export interface OrderCancel_orderCancel_order_fulfillments_lines_orderLine_variant {
|
||||
|
|
|
@ -54,10 +54,24 @@ export interface OrderCapture_orderCapture_order_events_user {
|
|||
email: string;
|
||||
}
|
||||
|
||||
export interface OrderCapture_orderCapture_order_events_lines_orderLine {
|
||||
__typename: "OrderLine";
|
||||
id: string;
|
||||
productName: string;
|
||||
variantName: string;
|
||||
}
|
||||
|
||||
export interface OrderCapture_orderCapture_order_events_lines {
|
||||
__typename: "OrderEventOrderLineObject";
|
||||
quantity: number | null;
|
||||
orderLine: OrderCapture_orderCapture_order_events_lines_orderLine | null;
|
||||
}
|
||||
|
||||
export interface OrderCapture_orderCapture_order_events {
|
||||
__typename: "OrderEvent";
|
||||
id: string;
|
||||
amount: number | null;
|
||||
shippingCostsIncluded: boolean | null;
|
||||
date: any | null;
|
||||
email: string | null;
|
||||
emailType: OrderEventsEmailsEnum | null;
|
||||
|
@ -67,6 +81,7 @@ export interface OrderCapture_orderCapture_order_events {
|
|||
transactionReference: string | null;
|
||||
type: OrderEventsEnum | null;
|
||||
user: OrderCapture_orderCapture_order_events_user | null;
|
||||
lines: (OrderCapture_orderCapture_order_events_lines | null)[] | null;
|
||||
}
|
||||
|
||||
export interface OrderCapture_orderCapture_order_fulfillments_lines_orderLine_variant {
|
||||
|
|
|
@ -54,18 +54,34 @@ export interface OrderConfirm_orderConfirm_order_events_user {
|
|||
email: string;
|
||||
}
|
||||
|
||||
export interface OrderConfirm_orderConfirm_order_events_lines_orderLine {
|
||||
__typename: "OrderLine";
|
||||
id: string;
|
||||
productName: string;
|
||||
variantName: string;
|
||||
}
|
||||
|
||||
export interface OrderConfirm_orderConfirm_order_events_lines {
|
||||
__typename: "OrderEventOrderLineObject";
|
||||
quantity: number | null;
|
||||
orderLine: OrderConfirm_orderConfirm_order_events_lines_orderLine | null;
|
||||
}
|
||||
|
||||
export interface OrderConfirm_orderConfirm_order_events {
|
||||
__typename: "OrderEvent";
|
||||
id: string;
|
||||
amount: number | null;
|
||||
shippingCostsIncluded: boolean | null;
|
||||
date: any | null;
|
||||
email: string | null;
|
||||
emailType: OrderEventsEmailsEnum | null;
|
||||
invoiceNumber: string | null;
|
||||
message: string | null;
|
||||
quantity: number | null;
|
||||
transactionReference: string | null;
|
||||
type: OrderEventsEnum | null;
|
||||
user: OrderConfirm_orderConfirm_order_events_user | null;
|
||||
lines: (OrderConfirm_orderConfirm_order_events_lines | null)[] | null;
|
||||
}
|
||||
|
||||
export interface OrderConfirm_orderConfirm_order_fulfillments_lines_orderLine_variant {
|
||||
|
@ -326,6 +342,7 @@ export interface OrderConfirm_orderConfirm_order {
|
|||
discount: OrderConfirm_orderConfirm_order_discount | null;
|
||||
invoices: (OrderConfirm_orderConfirm_order_invoices | null)[] | null;
|
||||
channel: OrderConfirm_orderConfirm_order_channel;
|
||||
isPaid: boolean | null;
|
||||
}
|
||||
|
||||
export interface OrderConfirm_orderConfirm {
|
||||
|
|
|
@ -48,10 +48,24 @@ export interface OrderDetails_order_events_user {
|
|||
email: string;
|
||||
}
|
||||
|
||||
export interface OrderDetails_order_events_lines_orderLine {
|
||||
__typename: "OrderLine";
|
||||
id: string;
|
||||
productName: string;
|
||||
variantName: string;
|
||||
}
|
||||
|
||||
export interface OrderDetails_order_events_lines {
|
||||
__typename: "OrderEventOrderLineObject";
|
||||
quantity: number | null;
|
||||
orderLine: OrderDetails_order_events_lines_orderLine | null;
|
||||
}
|
||||
|
||||
export interface OrderDetails_order_events {
|
||||
__typename: "OrderEvent";
|
||||
id: string;
|
||||
amount: number | null;
|
||||
shippingCostsIncluded: boolean | null;
|
||||
date: any | null;
|
||||
email: string | null;
|
||||
emailType: OrderEventsEmailsEnum | null;
|
||||
|
@ -61,6 +75,7 @@ export interface OrderDetails_order_events {
|
|||
transactionReference: string | null;
|
||||
type: OrderEventsEnum | null;
|
||||
user: OrderDetails_order_events_user | null;
|
||||
lines: (OrderDetails_order_events_lines | null)[] | null;
|
||||
}
|
||||
|
||||
export interface OrderDetails_order_fulfillments_lines_orderLine_variant {
|
||||
|
|
|
@ -54,10 +54,24 @@ export interface OrderDraftCancel_draftOrderDelete_order_events_user {
|
|||
email: string;
|
||||
}
|
||||
|
||||
export interface OrderDraftCancel_draftOrderDelete_order_events_lines_orderLine {
|
||||
__typename: "OrderLine";
|
||||
id: string;
|
||||
productName: string;
|
||||
variantName: string;
|
||||
}
|
||||
|
||||
export interface OrderDraftCancel_draftOrderDelete_order_events_lines {
|
||||
__typename: "OrderEventOrderLineObject";
|
||||
quantity: number | null;
|
||||
orderLine: OrderDraftCancel_draftOrderDelete_order_events_lines_orderLine | null;
|
||||
}
|
||||
|
||||
export interface OrderDraftCancel_draftOrderDelete_order_events {
|
||||
__typename: "OrderEvent";
|
||||
id: string;
|
||||
amount: number | null;
|
||||
shippingCostsIncluded: boolean | null;
|
||||
date: any | null;
|
||||
email: string | null;
|
||||
emailType: OrderEventsEmailsEnum | null;
|
||||
|
@ -67,6 +81,7 @@ export interface OrderDraftCancel_draftOrderDelete_order_events {
|
|||
transactionReference: string | null;
|
||||
type: OrderEventsEnum | null;
|
||||
user: OrderDraftCancel_draftOrderDelete_order_events_user | null;
|
||||
lines: (OrderDraftCancel_draftOrderDelete_order_events_lines | null)[] | null;
|
||||
}
|
||||
|
||||
export interface OrderDraftCancel_draftOrderDelete_order_fulfillments_lines_orderLine_variant {
|
||||
|
|
|
@ -54,10 +54,24 @@ export interface OrderDraftFinalize_draftOrderComplete_order_events_user {
|
|||
email: string;
|
||||
}
|
||||
|
||||
export interface OrderDraftFinalize_draftOrderComplete_order_events_lines_orderLine {
|
||||
__typename: "OrderLine";
|
||||
id: string;
|
||||
productName: string;
|
||||
variantName: string;
|
||||
}
|
||||
|
||||
export interface OrderDraftFinalize_draftOrderComplete_order_events_lines {
|
||||
__typename: "OrderEventOrderLineObject";
|
||||
quantity: number | null;
|
||||
orderLine: OrderDraftFinalize_draftOrderComplete_order_events_lines_orderLine | null;
|
||||
}
|
||||
|
||||
export interface OrderDraftFinalize_draftOrderComplete_order_events {
|
||||
__typename: "OrderEvent";
|
||||
id: string;
|
||||
amount: number | null;
|
||||
shippingCostsIncluded: boolean | null;
|
||||
date: any | null;
|
||||
email: string | null;
|
||||
emailType: OrderEventsEmailsEnum | null;
|
||||
|
@ -67,6 +81,7 @@ export interface OrderDraftFinalize_draftOrderComplete_order_events {
|
|||
transactionReference: string | null;
|
||||
type: OrderEventsEnum | null;
|
||||
user: OrderDraftFinalize_draftOrderComplete_order_events_user | null;
|
||||
lines: (OrderDraftFinalize_draftOrderComplete_order_events_lines | null)[] | null;
|
||||
}
|
||||
|
||||
export interface OrderDraftFinalize_draftOrderComplete_order_fulfillments_lines_orderLine_variant {
|
||||
|
|
|
@ -54,10 +54,24 @@ export interface OrderDraftUpdate_draftOrderUpdate_order_events_user {
|
|||
email: string;
|
||||
}
|
||||
|
||||
export interface OrderDraftUpdate_draftOrderUpdate_order_events_lines_orderLine {
|
||||
__typename: "OrderLine";
|
||||
id: string;
|
||||
productName: string;
|
||||
variantName: string;
|
||||
}
|
||||
|
||||
export interface OrderDraftUpdate_draftOrderUpdate_order_events_lines {
|
||||
__typename: "OrderEventOrderLineObject";
|
||||
quantity: number | null;
|
||||
orderLine: OrderDraftUpdate_draftOrderUpdate_order_events_lines_orderLine | null;
|
||||
}
|
||||
|
||||
export interface OrderDraftUpdate_draftOrderUpdate_order_events {
|
||||
__typename: "OrderEvent";
|
||||
id: string;
|
||||
amount: number | null;
|
||||
shippingCostsIncluded: boolean | null;
|
||||
date: any | null;
|
||||
email: string | null;
|
||||
emailType: OrderEventsEmailsEnum | null;
|
||||
|
@ -67,6 +81,7 @@ export interface OrderDraftUpdate_draftOrderUpdate_order_events {
|
|||
transactionReference: string | null;
|
||||
type: OrderEventsEnum | null;
|
||||
user: OrderDraftUpdate_draftOrderUpdate_order_events_user | null;
|
||||
lines: (OrderDraftUpdate_draftOrderUpdate_order_events_lines | null)[] | null;
|
||||
}
|
||||
|
||||
export interface OrderDraftUpdate_draftOrderUpdate_order_fulfillments_lines_orderLine_variant {
|
||||
|
|
|
@ -54,10 +54,24 @@ export interface OrderFulfillmentCancel_orderFulfillmentCancel_order_events_user
|
|||
email: string;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentCancel_orderFulfillmentCancel_order_events_lines_orderLine {
|
||||
__typename: "OrderLine";
|
||||
id: string;
|
||||
productName: string;
|
||||
variantName: string;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentCancel_orderFulfillmentCancel_order_events_lines {
|
||||
__typename: "OrderEventOrderLineObject";
|
||||
quantity: number | null;
|
||||
orderLine: OrderFulfillmentCancel_orderFulfillmentCancel_order_events_lines_orderLine | null;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentCancel_orderFulfillmentCancel_order_events {
|
||||
__typename: "OrderEvent";
|
||||
id: string;
|
||||
amount: number | null;
|
||||
shippingCostsIncluded: boolean | null;
|
||||
date: any | null;
|
||||
email: string | null;
|
||||
emailType: OrderEventsEmailsEnum | null;
|
||||
|
@ -67,6 +81,7 @@ export interface OrderFulfillmentCancel_orderFulfillmentCancel_order_events {
|
|||
transactionReference: string | null;
|
||||
type: OrderEventsEnum | null;
|
||||
user: OrderFulfillmentCancel_orderFulfillmentCancel_order_events_user | null;
|
||||
lines: (OrderFulfillmentCancel_orderFulfillmentCancel_order_events_lines | null)[] | null;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentCancel_orderFulfillmentCancel_order_fulfillments_lines_orderLine_variant {
|
||||
|
|
427
src/orders/types/OrderFulfillmentRefundProducts.ts
Normal file
427
src/orders/types/OrderFulfillmentRefundProducts.ts
Normal file
|
@ -0,0 +1,427 @@
|
|||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import { OrderRefundProductsInput, OrderErrorCode, FulfillmentStatus, OrderEventsEmailsEnum, OrderEventsEnum, PaymentChargeStatusEnum, OrderStatus, OrderAction, JobStatusEnum } from "./../../types/globalTypes";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL mutation operation: OrderFulfillmentRefundProducts
|
||||
// ====================================================
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_errors {
|
||||
__typename: "OrderError";
|
||||
code: OrderErrorCode;
|
||||
field: string | null;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_fulfillment_lines_orderLine_variant {
|
||||
__typename: "ProductVariant";
|
||||
id: string;
|
||||
quantityAvailable: number;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_fulfillment_lines_orderLine_unitPrice_gross {
|
||||
__typename: "Money";
|
||||
amount: number;
|
||||
currency: string;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_fulfillment_lines_orderLine_unitPrice_net {
|
||||
__typename: "Money";
|
||||
amount: number;
|
||||
currency: string;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_fulfillment_lines_orderLine_unitPrice {
|
||||
__typename: "TaxedMoney";
|
||||
gross: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_fulfillment_lines_orderLine_unitPrice_gross;
|
||||
net: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_fulfillment_lines_orderLine_unitPrice_net;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_fulfillment_lines_orderLine_thumbnail {
|
||||
__typename: "Image";
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_fulfillment_lines_orderLine {
|
||||
__typename: "OrderLine";
|
||||
id: string;
|
||||
isShippingRequired: boolean;
|
||||
variant: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_fulfillment_lines_orderLine_variant | null;
|
||||
productName: string;
|
||||
productSku: string;
|
||||
quantity: number;
|
||||
quantityFulfilled: number;
|
||||
unitPrice: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_fulfillment_lines_orderLine_unitPrice | null;
|
||||
thumbnail: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_fulfillment_lines_orderLine_thumbnail | null;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_fulfillment_lines {
|
||||
__typename: "FulfillmentLine";
|
||||
id: string;
|
||||
quantity: number;
|
||||
orderLine: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_fulfillment_lines_orderLine | null;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_fulfillment_warehouse {
|
||||
__typename: "Warehouse";
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_fulfillment {
|
||||
__typename: "Fulfillment";
|
||||
id: string;
|
||||
lines: (OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_fulfillment_lines | null)[] | null;
|
||||
fulfillmentOrder: number;
|
||||
status: FulfillmentStatus;
|
||||
trackingNumber: string;
|
||||
warehouse: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_fulfillment_warehouse | null;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_metadata {
|
||||
__typename: "MetadataItem";
|
||||
key: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_privateMetadata {
|
||||
__typename: "MetadataItem";
|
||||
key: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_billingAddress_country {
|
||||
__typename: "CountryDisplay";
|
||||
code: string;
|
||||
country: string;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_billingAddress {
|
||||
__typename: "Address";
|
||||
city: string;
|
||||
cityArea: string;
|
||||
companyName: string;
|
||||
country: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_billingAddress_country;
|
||||
countryArea: string;
|
||||
firstName: string;
|
||||
id: string;
|
||||
lastName: string;
|
||||
phone: string | null;
|
||||
postalCode: string;
|
||||
streetAddress1: string;
|
||||
streetAddress2: string;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_events_user {
|
||||
__typename: "User";
|
||||
id: string;
|
||||
email: string;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_events_lines_orderLine {
|
||||
__typename: "OrderLine";
|
||||
id: string;
|
||||
productName: string;
|
||||
variantName: string;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_events_lines {
|
||||
__typename: "OrderEventOrderLineObject";
|
||||
quantity: number | null;
|
||||
orderLine: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_events_lines_orderLine | null;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_events {
|
||||
__typename: "OrderEvent";
|
||||
id: string;
|
||||
amount: number | null;
|
||||
shippingCostsIncluded: boolean | null;
|
||||
date: any | null;
|
||||
email: string | null;
|
||||
emailType: OrderEventsEmailsEnum | null;
|
||||
invoiceNumber: string | null;
|
||||
message: string | null;
|
||||
quantity: number | null;
|
||||
transactionReference: string | null;
|
||||
type: OrderEventsEnum | null;
|
||||
user: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_events_user | null;
|
||||
lines: (OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_events_lines | null)[] | null;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_fulfillments_lines_orderLine_variant {
|
||||
__typename: "ProductVariant";
|
||||
id: string;
|
||||
quantityAvailable: number;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_fulfillments_lines_orderLine_unitPrice_gross {
|
||||
__typename: "Money";
|
||||
amount: number;
|
||||
currency: string;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_fulfillments_lines_orderLine_unitPrice_net {
|
||||
__typename: "Money";
|
||||
amount: number;
|
||||
currency: string;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_fulfillments_lines_orderLine_unitPrice {
|
||||
__typename: "TaxedMoney";
|
||||
gross: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_fulfillments_lines_orderLine_unitPrice_gross;
|
||||
net: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_fulfillments_lines_orderLine_unitPrice_net;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_fulfillments_lines_orderLine_thumbnail {
|
||||
__typename: "Image";
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_fulfillments_lines_orderLine {
|
||||
__typename: "OrderLine";
|
||||
id: string;
|
||||
isShippingRequired: boolean;
|
||||
variant: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_fulfillments_lines_orderLine_variant | null;
|
||||
productName: string;
|
||||
productSku: string;
|
||||
quantity: number;
|
||||
quantityFulfilled: number;
|
||||
unitPrice: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_fulfillments_lines_orderLine_unitPrice | null;
|
||||
thumbnail: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_fulfillments_lines_orderLine_thumbnail | null;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_fulfillments_lines {
|
||||
__typename: "FulfillmentLine";
|
||||
id: string;
|
||||
quantity: number;
|
||||
orderLine: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_fulfillments_lines_orderLine | null;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_fulfillments_warehouse {
|
||||
__typename: "Warehouse";
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_fulfillments {
|
||||
__typename: "Fulfillment";
|
||||
id: string;
|
||||
lines: (OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_fulfillments_lines | null)[] | null;
|
||||
fulfillmentOrder: number;
|
||||
status: FulfillmentStatus;
|
||||
trackingNumber: string;
|
||||
warehouse: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_fulfillments_warehouse | null;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_lines_variant {
|
||||
__typename: "ProductVariant";
|
||||
id: string;
|
||||
quantityAvailable: number;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_lines_unitPrice_gross {
|
||||
__typename: "Money";
|
||||
amount: number;
|
||||
currency: string;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_lines_unitPrice_net {
|
||||
__typename: "Money";
|
||||
amount: number;
|
||||
currency: string;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_lines_unitPrice {
|
||||
__typename: "TaxedMoney";
|
||||
gross: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_lines_unitPrice_gross;
|
||||
net: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_lines_unitPrice_net;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_lines_thumbnail {
|
||||
__typename: "Image";
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_lines {
|
||||
__typename: "OrderLine";
|
||||
id: string;
|
||||
isShippingRequired: boolean;
|
||||
variant: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_lines_variant | null;
|
||||
productName: string;
|
||||
productSku: string;
|
||||
quantity: number;
|
||||
quantityFulfilled: number;
|
||||
unitPrice: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_lines_unitPrice | null;
|
||||
thumbnail: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_lines_thumbnail | null;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_shippingAddress_country {
|
||||
__typename: "CountryDisplay";
|
||||
code: string;
|
||||
country: string;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_shippingAddress {
|
||||
__typename: "Address";
|
||||
city: string;
|
||||
cityArea: string;
|
||||
companyName: string;
|
||||
country: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_shippingAddress_country;
|
||||
countryArea: string;
|
||||
firstName: string;
|
||||
id: string;
|
||||
lastName: string;
|
||||
phone: string | null;
|
||||
postalCode: string;
|
||||
streetAddress1: string;
|
||||
streetAddress2: string;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_shippingMethod {
|
||||
__typename: "ShippingMethod";
|
||||
id: string;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_shippingPrice_gross {
|
||||
__typename: "Money";
|
||||
amount: number;
|
||||
currency: string;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_shippingPrice {
|
||||
__typename: "TaxedMoney";
|
||||
gross: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_shippingPrice_gross;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_subtotal_gross {
|
||||
__typename: "Money";
|
||||
amount: number;
|
||||
currency: string;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_subtotal {
|
||||
__typename: "TaxedMoney";
|
||||
gross: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_subtotal_gross;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_total_gross {
|
||||
__typename: "Money";
|
||||
amount: number;
|
||||
currency: string;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_total_tax {
|
||||
__typename: "Money";
|
||||
amount: number;
|
||||
currency: string;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_total {
|
||||
__typename: "TaxedMoney";
|
||||
gross: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_total_gross;
|
||||
tax: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_total_tax;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_totalAuthorized {
|
||||
__typename: "Money";
|
||||
amount: number;
|
||||
currency: string;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_totalCaptured {
|
||||
__typename: "Money";
|
||||
amount: number;
|
||||
currency: string;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_user {
|
||||
__typename: "User";
|
||||
id: string;
|
||||
email: string;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_availableShippingMethods_price {
|
||||
__typename: "Money";
|
||||
amount: number;
|
||||
currency: string;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_availableShippingMethods {
|
||||
__typename: "ShippingMethod";
|
||||
id: string;
|
||||
name: string;
|
||||
price: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_availableShippingMethods_price | null;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_discount {
|
||||
__typename: "Money";
|
||||
amount: number;
|
||||
currency: string;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_invoices {
|
||||
__typename: "Invoice";
|
||||
id: string;
|
||||
number: string | null;
|
||||
createdAt: any;
|
||||
url: string | null;
|
||||
status: JobStatusEnum;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_channel {
|
||||
__typename: "Channel";
|
||||
isActive: boolean;
|
||||
id: string;
|
||||
name: string;
|
||||
currencyCode: string;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order {
|
||||
__typename: "Order";
|
||||
id: string;
|
||||
metadata: (OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_metadata | null)[];
|
||||
privateMetadata: (OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_privateMetadata | null)[];
|
||||
billingAddress: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_billingAddress | null;
|
||||
canFinalize: boolean;
|
||||
created: any;
|
||||
customerNote: string;
|
||||
events: (OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_events | null)[] | null;
|
||||
fulfillments: (OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_fulfillments | null)[];
|
||||
lines: (OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_lines | null)[];
|
||||
number: string | null;
|
||||
paymentStatus: PaymentChargeStatusEnum | null;
|
||||
shippingAddress: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_shippingAddress | null;
|
||||
shippingMethod: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_shippingMethod | null;
|
||||
shippingMethodName: string | null;
|
||||
shippingPrice: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_shippingPrice | null;
|
||||
status: OrderStatus;
|
||||
subtotal: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_subtotal | null;
|
||||
total: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_total | null;
|
||||
actions: (OrderAction | null)[];
|
||||
totalAuthorized: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_totalAuthorized | null;
|
||||
totalCaptured: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_totalCaptured | null;
|
||||
user: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_user | null;
|
||||
userEmail: string | null;
|
||||
availableShippingMethods: (OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_availableShippingMethods | null)[] | null;
|
||||
discount: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_discount | null;
|
||||
invoices: (OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_invoices | null)[] | null;
|
||||
channel: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_channel;
|
||||
isPaid: boolean | null;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts {
|
||||
__typename: "FulfillmentRefundProducts";
|
||||
errors: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_errors[];
|
||||
fulfillment: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_fulfillment | null;
|
||||
order: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order | null;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProducts {
|
||||
orderFulfillmentRefundProducts: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts | null;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentRefundProductsVariables {
|
||||
input: OrderRefundProductsInput;
|
||||
order: string;
|
||||
}
|
|
@ -54,10 +54,24 @@ export interface OrderFulfillmentUpdateTracking_orderFulfillmentUpdateTracking_o
|
|||
email: string;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentUpdateTracking_orderFulfillmentUpdateTracking_order_events_lines_orderLine {
|
||||
__typename: "OrderLine";
|
||||
id: string;
|
||||
productName: string;
|
||||
variantName: string;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentUpdateTracking_orderFulfillmentUpdateTracking_order_events_lines {
|
||||
__typename: "OrderEventOrderLineObject";
|
||||
quantity: number | null;
|
||||
orderLine: OrderFulfillmentUpdateTracking_orderFulfillmentUpdateTracking_order_events_lines_orderLine | null;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentUpdateTracking_orderFulfillmentUpdateTracking_order_events {
|
||||
__typename: "OrderEvent";
|
||||
id: string;
|
||||
amount: number | null;
|
||||
shippingCostsIncluded: boolean | null;
|
||||
date: any | null;
|
||||
email: string | null;
|
||||
emailType: OrderEventsEmailsEnum | null;
|
||||
|
@ -67,6 +81,7 @@ export interface OrderFulfillmentUpdateTracking_orderFulfillmentUpdateTracking_o
|
|||
transactionReference: string | null;
|
||||
type: OrderEventsEnum | null;
|
||||
user: OrderFulfillmentUpdateTracking_orderFulfillmentUpdateTracking_order_events_user | null;
|
||||
lines: (OrderFulfillmentUpdateTracking_orderFulfillmentUpdateTracking_order_events_lines | null)[] | null;
|
||||
}
|
||||
|
||||
export interface OrderFulfillmentUpdateTracking_orderFulfillmentUpdateTracking_order_fulfillments_lines_orderLine_variant {
|
||||
|
|
|
@ -54,10 +54,24 @@ export interface OrderLineDelete_draftOrderLineDelete_order_events_user {
|
|||
email: string;
|
||||
}
|
||||
|
||||
export interface OrderLineDelete_draftOrderLineDelete_order_events_lines_orderLine {
|
||||
__typename: "OrderLine";
|
||||
id: string;
|
||||
productName: string;
|
||||
variantName: string;
|
||||
}
|
||||
|
||||
export interface OrderLineDelete_draftOrderLineDelete_order_events_lines {
|
||||
__typename: "OrderEventOrderLineObject";
|
||||
quantity: number | null;
|
||||
orderLine: OrderLineDelete_draftOrderLineDelete_order_events_lines_orderLine | null;
|
||||
}
|
||||
|
||||
export interface OrderLineDelete_draftOrderLineDelete_order_events {
|
||||
__typename: "OrderEvent";
|
||||
id: string;
|
||||
amount: number | null;
|
||||
shippingCostsIncluded: boolean | null;
|
||||
date: any | null;
|
||||
email: string | null;
|
||||
emailType: OrderEventsEmailsEnum | null;
|
||||
|
@ -67,6 +81,7 @@ export interface OrderLineDelete_draftOrderLineDelete_order_events {
|
|||
transactionReference: string | null;
|
||||
type: OrderEventsEnum | null;
|
||||
user: OrderLineDelete_draftOrderLineDelete_order_events_user | null;
|
||||
lines: (OrderLineDelete_draftOrderLineDelete_order_events_lines | null)[] | null;
|
||||
}
|
||||
|
||||
export interface OrderLineDelete_draftOrderLineDelete_order_fulfillments_lines_orderLine_variant {
|
||||
|
|
|
@ -54,10 +54,24 @@ export interface OrderLineUpdate_draftOrderLineUpdate_order_events_user {
|
|||
email: string;
|
||||
}
|
||||
|
||||
export interface OrderLineUpdate_draftOrderLineUpdate_order_events_lines_orderLine {
|
||||
__typename: "OrderLine";
|
||||
id: string;
|
||||
productName: string;
|
||||
variantName: string;
|
||||
}
|
||||
|
||||
export interface OrderLineUpdate_draftOrderLineUpdate_order_events_lines {
|
||||
__typename: "OrderEventOrderLineObject";
|
||||
quantity: number | null;
|
||||
orderLine: OrderLineUpdate_draftOrderLineUpdate_order_events_lines_orderLine | null;
|
||||
}
|
||||
|
||||
export interface OrderLineUpdate_draftOrderLineUpdate_order_events {
|
||||
__typename: "OrderEvent";
|
||||
id: string;
|
||||
amount: number | null;
|
||||
shippingCostsIncluded: boolean | null;
|
||||
date: any | null;
|
||||
email: string | null;
|
||||
emailType: OrderEventsEmailsEnum | null;
|
||||
|
@ -67,6 +81,7 @@ export interface OrderLineUpdate_draftOrderLineUpdate_order_events {
|
|||
transactionReference: string | null;
|
||||
type: OrderEventsEnum | null;
|
||||
user: OrderLineUpdate_draftOrderLineUpdate_order_events_user | null;
|
||||
lines: (OrderLineUpdate_draftOrderLineUpdate_order_events_lines | null)[] | null;
|
||||
}
|
||||
|
||||
export interface OrderLineUpdate_draftOrderLineUpdate_order_fulfillments_lines_orderLine_variant {
|
||||
|
|
|
@ -54,10 +54,24 @@ export interface OrderLinesAdd_draftOrderLinesCreate_order_events_user {
|
|||
email: string;
|
||||
}
|
||||
|
||||
export interface OrderLinesAdd_draftOrderLinesCreate_order_events_lines_orderLine {
|
||||
__typename: "OrderLine";
|
||||
id: string;
|
||||
productName: string;
|
||||
variantName: string;
|
||||
}
|
||||
|
||||
export interface OrderLinesAdd_draftOrderLinesCreate_order_events_lines {
|
||||
__typename: "OrderEventOrderLineObject";
|
||||
quantity: number | null;
|
||||
orderLine: OrderLinesAdd_draftOrderLinesCreate_order_events_lines_orderLine | null;
|
||||
}
|
||||
|
||||
export interface OrderLinesAdd_draftOrderLinesCreate_order_events {
|
||||
__typename: "OrderEvent";
|
||||
id: string;
|
||||
amount: number | null;
|
||||
shippingCostsIncluded: boolean | null;
|
||||
date: any | null;
|
||||
email: string | null;
|
||||
emailType: OrderEventsEmailsEnum | null;
|
||||
|
@ -67,6 +81,7 @@ export interface OrderLinesAdd_draftOrderLinesCreate_order_events {
|
|||
transactionReference: string | null;
|
||||
type: OrderEventsEnum | null;
|
||||
user: OrderLinesAdd_draftOrderLinesCreate_order_events_user | null;
|
||||
lines: (OrderLinesAdd_draftOrderLinesCreate_order_events_lines | null)[] | null;
|
||||
}
|
||||
|
||||
export interface OrderLinesAdd_draftOrderLinesCreate_order_fulfillments_lines_orderLine_variant {
|
||||
|
|
|
@ -54,10 +54,24 @@ export interface OrderMarkAsPaid_orderMarkAsPaid_order_events_user {
|
|||
email: string;
|
||||
}
|
||||
|
||||
export interface OrderMarkAsPaid_orderMarkAsPaid_order_events_lines_orderLine {
|
||||
__typename: "OrderLine";
|
||||
id: string;
|
||||
productName: string;
|
||||
variantName: string;
|
||||
}
|
||||
|
||||
export interface OrderMarkAsPaid_orderMarkAsPaid_order_events_lines {
|
||||
__typename: "OrderEventOrderLineObject";
|
||||
quantity: number | null;
|
||||
orderLine: OrderMarkAsPaid_orderMarkAsPaid_order_events_lines_orderLine | null;
|
||||
}
|
||||
|
||||
export interface OrderMarkAsPaid_orderMarkAsPaid_order_events {
|
||||
__typename: "OrderEvent";
|
||||
id: string;
|
||||
amount: number | null;
|
||||
shippingCostsIncluded: boolean | null;
|
||||
date: any | null;
|
||||
email: string | null;
|
||||
emailType: OrderEventsEmailsEnum | null;
|
||||
|
@ -67,6 +81,7 @@ export interface OrderMarkAsPaid_orderMarkAsPaid_order_events {
|
|||
transactionReference: string | null;
|
||||
type: OrderEventsEnum | null;
|
||||
user: OrderMarkAsPaid_orderMarkAsPaid_order_events_user | null;
|
||||
lines: (OrderMarkAsPaid_orderMarkAsPaid_order_events_lines | null)[] | null;
|
||||
}
|
||||
|
||||
export interface OrderMarkAsPaid_orderMarkAsPaid_order_fulfillments_lines_orderLine_variant {
|
||||
|
|
|
@ -54,10 +54,24 @@ export interface OrderRefund_orderRefund_order_events_user {
|
|||
email: string;
|
||||
}
|
||||
|
||||
export interface OrderRefund_orderRefund_order_events_lines_orderLine {
|
||||
__typename: "OrderLine";
|
||||
id: string;
|
||||
productName: string;
|
||||
variantName: string;
|
||||
}
|
||||
|
||||
export interface OrderRefund_orderRefund_order_events_lines {
|
||||
__typename: "OrderEventOrderLineObject";
|
||||
quantity: number | null;
|
||||
orderLine: OrderRefund_orderRefund_order_events_lines_orderLine | null;
|
||||
}
|
||||
|
||||
export interface OrderRefund_orderRefund_order_events {
|
||||
__typename: "OrderEvent";
|
||||
id: string;
|
||||
amount: number | null;
|
||||
shippingCostsIncluded: boolean | null;
|
||||
date: any | null;
|
||||
email: string | null;
|
||||
emailType: OrderEventsEmailsEnum | null;
|
||||
|
@ -67,6 +81,7 @@ export interface OrderRefund_orderRefund_order_events {
|
|||
transactionReference: string | null;
|
||||
type: OrderEventsEnum | null;
|
||||
user: OrderRefund_orderRefund_order_events_user | null;
|
||||
lines: (OrderRefund_orderRefund_order_events_lines | null)[] | null;
|
||||
}
|
||||
|
||||
export interface OrderRefund_orderRefund_order_fulfillments_lines_orderLine_variant {
|
||||
|
|
122
src/orders/types/OrderRefundData.ts
Normal file
122
src/orders/types/OrderRefundData.ts
Normal file
|
@ -0,0 +1,122 @@
|
|||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import { FulfillmentStatus } from "./../../types/globalTypes";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL query operation: OrderRefundData
|
||||
// ====================================================
|
||||
|
||||
export interface OrderRefundData_order_total_gross {
|
||||
__typename: "Money";
|
||||
amount: number;
|
||||
currency: string;
|
||||
}
|
||||
|
||||
export interface OrderRefundData_order_total {
|
||||
__typename: "TaxedMoney";
|
||||
gross: OrderRefundData_order_total_gross;
|
||||
}
|
||||
|
||||
export interface OrderRefundData_order_totalCaptured {
|
||||
__typename: "Money";
|
||||
amount: number;
|
||||
currency: string;
|
||||
}
|
||||
|
||||
export interface OrderRefundData_order_shippingPrice_gross {
|
||||
__typename: "Money";
|
||||
amount: number;
|
||||
currency: string;
|
||||
}
|
||||
|
||||
export interface OrderRefundData_order_shippingPrice {
|
||||
__typename: "TaxedMoney";
|
||||
gross: OrderRefundData_order_shippingPrice_gross;
|
||||
}
|
||||
|
||||
export interface OrderRefundData_order_lines_unitPrice_gross {
|
||||
__typename: "Money";
|
||||
amount: number;
|
||||
currency: string;
|
||||
}
|
||||
|
||||
export interface OrderRefundData_order_lines_unitPrice {
|
||||
__typename: "TaxedMoney";
|
||||
gross: OrderRefundData_order_lines_unitPrice_gross;
|
||||
}
|
||||
|
||||
export interface OrderRefundData_order_lines_thumbnail {
|
||||
__typename: "Image";
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface OrderRefundData_order_lines {
|
||||
__typename: "OrderLine";
|
||||
id: string;
|
||||
productName: string;
|
||||
quantity: number;
|
||||
unitPrice: OrderRefundData_order_lines_unitPrice | null;
|
||||
thumbnail: OrderRefundData_order_lines_thumbnail | null;
|
||||
quantityFulfilled: number;
|
||||
}
|
||||
|
||||
export interface OrderRefundData_order_fulfillments_lines_orderLine_unitPrice_gross {
|
||||
__typename: "Money";
|
||||
amount: number;
|
||||
currency: string;
|
||||
}
|
||||
|
||||
export interface OrderRefundData_order_fulfillments_lines_orderLine_unitPrice {
|
||||
__typename: "TaxedMoney";
|
||||
gross: OrderRefundData_order_fulfillments_lines_orderLine_unitPrice_gross;
|
||||
}
|
||||
|
||||
export interface OrderRefundData_order_fulfillments_lines_orderLine_thumbnail {
|
||||
__typename: "Image";
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface OrderRefundData_order_fulfillments_lines_orderLine {
|
||||
__typename: "OrderLine";
|
||||
id: string;
|
||||
productName: string;
|
||||
quantity: number;
|
||||
unitPrice: OrderRefundData_order_fulfillments_lines_orderLine_unitPrice | null;
|
||||
thumbnail: OrderRefundData_order_fulfillments_lines_orderLine_thumbnail | null;
|
||||
}
|
||||
|
||||
export interface OrderRefundData_order_fulfillments_lines {
|
||||
__typename: "FulfillmentLine";
|
||||
id: string;
|
||||
quantity: number;
|
||||
orderLine: OrderRefundData_order_fulfillments_lines_orderLine | null;
|
||||
}
|
||||
|
||||
export interface OrderRefundData_order_fulfillments {
|
||||
__typename: "Fulfillment";
|
||||
id: string;
|
||||
status: FulfillmentStatus;
|
||||
fulfillmentOrder: number;
|
||||
lines: (OrderRefundData_order_fulfillments_lines | null)[] | null;
|
||||
}
|
||||
|
||||
export interface OrderRefundData_order {
|
||||
__typename: "Order";
|
||||
id: string;
|
||||
number: string | null;
|
||||
total: OrderRefundData_order_total | null;
|
||||
totalCaptured: OrderRefundData_order_totalCaptured | null;
|
||||
shippingPrice: OrderRefundData_order_shippingPrice | null;
|
||||
lines: (OrderRefundData_order_lines | null)[];
|
||||
fulfillments: (OrderRefundData_order_fulfillments | null)[];
|
||||
}
|
||||
|
||||
export interface OrderRefundData {
|
||||
order: OrderRefundData_order | null;
|
||||
}
|
||||
|
||||
export interface OrderRefundDataVariables {
|
||||
orderId: string;
|
||||
}
|
|
@ -54,10 +54,24 @@ export interface OrderUpdate_orderUpdate_order_events_user {
|
|||
email: string;
|
||||
}
|
||||
|
||||
export interface OrderUpdate_orderUpdate_order_events_lines_orderLine {
|
||||
__typename: "OrderLine";
|
||||
id: string;
|
||||
productName: string;
|
||||
variantName: string;
|
||||
}
|
||||
|
||||
export interface OrderUpdate_orderUpdate_order_events_lines {
|
||||
__typename: "OrderEventOrderLineObject";
|
||||
quantity: number | null;
|
||||
orderLine: OrderUpdate_orderUpdate_order_events_lines_orderLine | null;
|
||||
}
|
||||
|
||||
export interface OrderUpdate_orderUpdate_order_events {
|
||||
__typename: "OrderEvent";
|
||||
id: string;
|
||||
amount: number | null;
|
||||
shippingCostsIncluded: boolean | null;
|
||||
date: any | null;
|
||||
email: string | null;
|
||||
emailType: OrderEventsEmailsEnum | null;
|
||||
|
@ -67,6 +81,7 @@ export interface OrderUpdate_orderUpdate_order_events {
|
|||
transactionReference: string | null;
|
||||
type: OrderEventsEnum | null;
|
||||
user: OrderUpdate_orderUpdate_order_events_user | null;
|
||||
lines: (OrderUpdate_orderUpdate_order_events_lines | null)[] | null;
|
||||
}
|
||||
|
||||
export interface OrderUpdate_orderUpdate_order_fulfillments_lines_orderLine_variant {
|
||||
|
|
|
@ -54,10 +54,24 @@ export interface OrderVoid_orderVoid_order_events_user {
|
|||
email: string;
|
||||
}
|
||||
|
||||
export interface OrderVoid_orderVoid_order_events_lines_orderLine {
|
||||
__typename: "OrderLine";
|
||||
id: string;
|
||||
productName: string;
|
||||
variantName: string;
|
||||
}
|
||||
|
||||
export interface OrderVoid_orderVoid_order_events_lines {
|
||||
__typename: "OrderEventOrderLineObject";
|
||||
quantity: number | null;
|
||||
orderLine: OrderVoid_orderVoid_order_events_lines_orderLine | null;
|
||||
}
|
||||
|
||||
export interface OrderVoid_orderVoid_order_events {
|
||||
__typename: "OrderEvent";
|
||||
id: string;
|
||||
amount: number | null;
|
||||
shippingCostsIncluded: boolean | null;
|
||||
date: any | null;
|
||||
email: string | null;
|
||||
emailType: OrderEventsEmailsEnum | null;
|
||||
|
@ -67,6 +81,7 @@ export interface OrderVoid_orderVoid_order_events {
|
|||
transactionReference: string | null;
|
||||
type: OrderEventsEnum | null;
|
||||
user: OrderVoid_orderVoid_order_events_user | null;
|
||||
lines: (OrderVoid_orderVoid_order_events_lines | null)[] | null;
|
||||
}
|
||||
|
||||
export interface OrderVoid_orderVoid_order_fulfillments_lines_orderLine_variant {
|
||||
|
|
|
@ -103,7 +103,6 @@ export type OrderUrlDialog =
|
|||
| "edit-shipping-address"
|
||||
| "finalize"
|
||||
| "mark-paid"
|
||||
| "refund"
|
||||
| "void"
|
||||
| "invoice-send";
|
||||
export type OrderUrlQueryParams = Dialog<OrderUrlDialog> & SingleAction;
|
||||
|
@ -116,3 +115,7 @@ export const orderFulfillUrl = (id: string) =>
|
|||
orderFulfillPath(encodeURIComponent(id));
|
||||
|
||||
export const orderSettingsPath = urlJoin(orderSectionUrl, "settings");
|
||||
|
||||
export const orderRefundPath = (id: string) => urlJoin(orderPath(id), "refund");
|
||||
export const orderRefundUrl = (id: string) =>
|
||||
orderRefundPath(encodeURIComponent(id));
|
||||
|
|
525
src/orders/utils/data.test.ts
Normal file
525
src/orders/utils/data.test.ts
Normal file
|
@ -0,0 +1,525 @@
|
|||
/* eslint-disable sort-keys */
|
||||
import { FormsetData } from "@saleor/hooks/useFormset";
|
||||
import { FulfillmentStatus } from "@saleor/types/globalTypes";
|
||||
|
||||
import { OrderDetails_order_fulfillments_lines } from "../types/OrderDetails";
|
||||
import {
|
||||
OrderRefundData_order_fulfillments,
|
||||
OrderRefundData_order_lines
|
||||
} from "../types/OrderRefundData";
|
||||
import {
|
||||
getAllFulfillmentLinesPriceSum,
|
||||
getPreviouslyRefundedPrice,
|
||||
getRefundedLinesPriceSum,
|
||||
mergeRepeatedOrderLines,
|
||||
OrderWithTotalAndTotalCaptured
|
||||
} from "./data";
|
||||
|
||||
describe("Get previously refunded price", () => {
|
||||
it("is able to calculate refunded price from order", () => {
|
||||
const order: OrderWithTotalAndTotalCaptured = {
|
||||
total: {
|
||||
__typename: "TaxedMoney",
|
||||
gross: {
|
||||
__typename: "Money",
|
||||
amount: 160,
|
||||
currency: "USD"
|
||||
}
|
||||
},
|
||||
totalCaptured: {
|
||||
__typename: "Money",
|
||||
amount: 100,
|
||||
currency: "USD"
|
||||
}
|
||||
};
|
||||
|
||||
const refundedPrice = getPreviouslyRefundedPrice(order);
|
||||
|
||||
expect(refundedPrice.amount).toBe(-60);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Get refunded lines price sum", () => {
|
||||
const lines: OrderRefundData_order_lines[] = [
|
||||
{
|
||||
__typename: "OrderLine",
|
||||
id: "1",
|
||||
productName: "Milk 1",
|
||||
quantity: 1,
|
||||
quantityFulfilled: 1,
|
||||
thumbnail: undefined,
|
||||
unitPrice: {
|
||||
__typename: "TaxedMoney",
|
||||
gross: {
|
||||
__typename: "Money",
|
||||
amount: 10,
|
||||
currency: "USD"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
__typename: "OrderLine",
|
||||
id: "2",
|
||||
productName: "Milk 2",
|
||||
quantity: 2,
|
||||
quantityFulfilled: 2,
|
||||
thumbnail: undefined,
|
||||
unitPrice: {
|
||||
__typename: "TaxedMoney",
|
||||
gross: {
|
||||
__typename: "Money",
|
||||
amount: 6,
|
||||
currency: "USD"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
__typename: "OrderLine",
|
||||
id: "3",
|
||||
productName: "Milk 3",
|
||||
quantity: 4,
|
||||
quantityFulfilled: 4,
|
||||
thumbnail: undefined,
|
||||
unitPrice: {
|
||||
__typename: "TaxedMoney",
|
||||
gross: {
|
||||
__typename: "Money",
|
||||
amount: 4,
|
||||
currency: "USD"
|
||||
}
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
it("is able to sum lines prices", () => {
|
||||
const refundedProductQuantities: FormsetData<null, string> = [
|
||||
{
|
||||
data: null,
|
||||
id: "1",
|
||||
label: null,
|
||||
value: "1"
|
||||
},
|
||||
{
|
||||
data: null,
|
||||
id: "2",
|
||||
label: null,
|
||||
value: "1"
|
||||
},
|
||||
{
|
||||
data: null,
|
||||
id: "3",
|
||||
label: null,
|
||||
value: "1"
|
||||
}
|
||||
];
|
||||
|
||||
const refundedLinesPriceSum = getRefundedLinesPriceSum(
|
||||
lines,
|
||||
refundedProductQuantities
|
||||
);
|
||||
|
||||
expect(refundedLinesPriceSum).toBe(20);
|
||||
});
|
||||
|
||||
it("is able to sum lines prices multiplied by different quantities", () => {
|
||||
const refundedProductQuantities: FormsetData<null, string> = [
|
||||
{
|
||||
data: null,
|
||||
id: "1",
|
||||
label: null,
|
||||
value: "0"
|
||||
},
|
||||
{
|
||||
data: null,
|
||||
id: "2",
|
||||
label: null,
|
||||
value: "2"
|
||||
},
|
||||
{
|
||||
data: null,
|
||||
id: "3",
|
||||
label: null,
|
||||
value: "4"
|
||||
}
|
||||
];
|
||||
|
||||
const refundedLinesPriceSum = getRefundedLinesPriceSum(
|
||||
lines,
|
||||
refundedProductQuantities
|
||||
);
|
||||
|
||||
expect(refundedLinesPriceSum).toBe(28);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Get get all fulfillment lines price sum", () => {
|
||||
const fulfillments: OrderRefundData_order_fulfillments[] = [
|
||||
{
|
||||
__typename: "Fulfillment",
|
||||
fulfillmentOrder: 1,
|
||||
id: "1",
|
||||
lines: [
|
||||
{
|
||||
__typename: "FulfillmentLine",
|
||||
id: "1-fulfillment-1",
|
||||
orderLine: {
|
||||
__typename: "OrderLine",
|
||||
id: "1-line-1",
|
||||
productName: "Milk 1",
|
||||
quantity: 1,
|
||||
thumbnail: undefined,
|
||||
unitPrice: {
|
||||
__typename: "TaxedMoney",
|
||||
gross: {
|
||||
__typename: "Money",
|
||||
amount: 10,
|
||||
currency: "USD"
|
||||
}
|
||||
}
|
||||
},
|
||||
quantity: 1
|
||||
}
|
||||
],
|
||||
status: FulfillmentStatus.FULFILLED
|
||||
},
|
||||
{
|
||||
__typename: "Fulfillment",
|
||||
fulfillmentOrder: 2,
|
||||
id: "2",
|
||||
lines: [
|
||||
{
|
||||
__typename: "FulfillmentLine",
|
||||
id: "2-fulfillment-1",
|
||||
orderLine: {
|
||||
__typename: "OrderLine",
|
||||
id: "2-line-1",
|
||||
productName: "Milk 1",
|
||||
quantity: 2,
|
||||
thumbnail: undefined,
|
||||
unitPrice: {
|
||||
__typename: "TaxedMoney",
|
||||
gross: {
|
||||
__typename: "Money",
|
||||
amount: 6,
|
||||
currency: "USD"
|
||||
}
|
||||
}
|
||||
},
|
||||
quantity: 1
|
||||
},
|
||||
{
|
||||
__typename: "FulfillmentLine",
|
||||
id: "2-fulfillment-2",
|
||||
orderLine: {
|
||||
__typename: "OrderLine",
|
||||
id: "2-line-2",
|
||||
productName: "Milk 2",
|
||||
quantity: 2,
|
||||
thumbnail: undefined,
|
||||
unitPrice: {
|
||||
__typename: "TaxedMoney",
|
||||
gross: {
|
||||
__typename: "Money",
|
||||
amount: 6,
|
||||
currency: "USD"
|
||||
}
|
||||
}
|
||||
},
|
||||
quantity: 1
|
||||
}
|
||||
],
|
||||
status: FulfillmentStatus.FULFILLED
|
||||
},
|
||||
{
|
||||
__typename: "Fulfillment",
|
||||
fulfillmentOrder: 1,
|
||||
id: "3",
|
||||
lines: [
|
||||
{
|
||||
__typename: "FulfillmentLine",
|
||||
id: "3-fulfillment-1",
|
||||
orderLine: {
|
||||
__typename: "OrderLine",
|
||||
id: "3-line-1",
|
||||
productName: "Milk 1",
|
||||
quantity: 4,
|
||||
thumbnail: undefined,
|
||||
unitPrice: {
|
||||
__typename: "TaxedMoney",
|
||||
gross: {
|
||||
__typename: "Money",
|
||||
amount: 4,
|
||||
currency: "USD"
|
||||
}
|
||||
}
|
||||
},
|
||||
quantity: 1
|
||||
},
|
||||
{
|
||||
__typename: "FulfillmentLine",
|
||||
id: "3-fulfillment-2",
|
||||
orderLine: {
|
||||
__typename: "OrderLine",
|
||||
id: "3-line-2",
|
||||
productName: "Milk 2",
|
||||
quantity: 4,
|
||||
thumbnail: undefined,
|
||||
unitPrice: {
|
||||
__typename: "TaxedMoney",
|
||||
gross: {
|
||||
__typename: "Money",
|
||||
amount: 4,
|
||||
currency: "USD"
|
||||
}
|
||||
}
|
||||
},
|
||||
quantity: 1
|
||||
},
|
||||
{
|
||||
__typename: "FulfillmentLine",
|
||||
id: "3-fulfillment-3",
|
||||
orderLine: {
|
||||
__typename: "OrderLine",
|
||||
id: "3-line-3",
|
||||
productName: "Milk 3",
|
||||
quantity: 4,
|
||||
thumbnail: undefined,
|
||||
unitPrice: {
|
||||
__typename: "TaxedMoney",
|
||||
gross: {
|
||||
__typename: "Money",
|
||||
amount: 4,
|
||||
currency: "USD"
|
||||
}
|
||||
}
|
||||
},
|
||||
quantity: 1
|
||||
}
|
||||
],
|
||||
status: FulfillmentStatus.FULFILLED
|
||||
}
|
||||
];
|
||||
|
||||
it("is able to sum fulfillment lines prices", () => {
|
||||
const refundedFulfilledProductQuantities: FormsetData<null, string> = [
|
||||
{
|
||||
data: null,
|
||||
id: "1-fulfillment-1",
|
||||
label: null,
|
||||
value: "1"
|
||||
},
|
||||
{
|
||||
data: null,
|
||||
id: "2-fulfillment-1",
|
||||
label: null,
|
||||
value: "1"
|
||||
},
|
||||
{
|
||||
data: null,
|
||||
id: "2-fulfillment-2",
|
||||
label: null,
|
||||
value: "1"
|
||||
},
|
||||
{
|
||||
data: null,
|
||||
id: "3-fulfillment-1",
|
||||
label: null,
|
||||
value: "1"
|
||||
},
|
||||
{
|
||||
data: null,
|
||||
id: "3-fulfillment-2",
|
||||
label: null,
|
||||
value: "1"
|
||||
},
|
||||
{
|
||||
data: null,
|
||||
id: "3-fulfillment-3",
|
||||
label: null,
|
||||
value: "1"
|
||||
}
|
||||
];
|
||||
|
||||
const allFulfillmentLinesPriceSum = getAllFulfillmentLinesPriceSum(
|
||||
fulfillments,
|
||||
refundedFulfilledProductQuantities
|
||||
);
|
||||
|
||||
expect(allFulfillmentLinesPriceSum).toBe(34);
|
||||
});
|
||||
|
||||
it("is able to sum fulfillment lines prices multiplied by different quantities", () => {
|
||||
const refundedFulfilledProductQuantities: FormsetData<null, string> = [
|
||||
{
|
||||
data: null,
|
||||
id: "1-fulfillment-1",
|
||||
label: null,
|
||||
value: "0"
|
||||
},
|
||||
{
|
||||
data: null,
|
||||
id: "2-fulfillment-1",
|
||||
label: null,
|
||||
value: "2"
|
||||
},
|
||||
{
|
||||
data: null,
|
||||
id: "2-fulfillment-2",
|
||||
label: null,
|
||||
value: "2"
|
||||
},
|
||||
{
|
||||
data: null,
|
||||
id: "3-fulfillment-1",
|
||||
label: null,
|
||||
value: "4"
|
||||
},
|
||||
{
|
||||
data: null,
|
||||
id: "3-fulfillment-2",
|
||||
label: null,
|
||||
value: "4"
|
||||
},
|
||||
{
|
||||
data: null,
|
||||
id: "3-fulfillment-3",
|
||||
label: null,
|
||||
value: "4"
|
||||
}
|
||||
];
|
||||
|
||||
const allFulfillmentLinesPriceSum = getAllFulfillmentLinesPriceSum(
|
||||
fulfillments,
|
||||
refundedFulfilledProductQuantities
|
||||
);
|
||||
|
||||
expect(allFulfillmentLinesPriceSum).toBe(72);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Merge repeated order lines of fulfillment lines", () => {
|
||||
it("is able to merge repeated order lines and sum their quantities", () => {
|
||||
const lines: OrderDetails_order_fulfillments_lines[] = [
|
||||
{
|
||||
id: "RnVsZmlsbG1lbnRMaW5lOjMx",
|
||||
quantity: 1,
|
||||
orderLine: {
|
||||
id: "T3JkZXJMaW5lOjQ1",
|
||||
isShippingRequired: false,
|
||||
variant: {
|
||||
id: "UHJvZHVjdFZhcmlhbnQ6MzE3",
|
||||
quantityAvailable: 50,
|
||||
__typename: "ProductVariant"
|
||||
},
|
||||
productName: "Lake Tunes",
|
||||
productSku: "lake-tunes-mp3",
|
||||
quantity: 2,
|
||||
quantityFulfilled: 2,
|
||||
unitPrice: {
|
||||
gross: {
|
||||
amount: 9.99,
|
||||
currency: "USD",
|
||||
__typename: "Money"
|
||||
},
|
||||
net: {
|
||||
amount: 9.99,
|
||||
currency: "USD",
|
||||
__typename: "Money"
|
||||
},
|
||||
__typename: "TaxedMoney"
|
||||
},
|
||||
thumbnail: {
|
||||
url:
|
||||
"http://localhost:8000/media/__sized__/products/saleor-digital-03_2-thumbnail-255x255.png",
|
||||
__typename: "Image"
|
||||
},
|
||||
__typename: "OrderLine"
|
||||
},
|
||||
__typename: "FulfillmentLine"
|
||||
},
|
||||
{
|
||||
id: "RnVsZmlsbG1lbnRMaW5lOjMy",
|
||||
quantity: 1,
|
||||
orderLine: {
|
||||
id: "T3JkZXJMaW5lOjQ1",
|
||||
isShippingRequired: false,
|
||||
variant: {
|
||||
id: "UHJvZHVjdFZhcmlhbnQ6MzE3",
|
||||
quantityAvailable: 50,
|
||||
__typename: "ProductVariant"
|
||||
},
|
||||
productName: "Lake Tunes",
|
||||
productSku: "lake-tunes-mp3",
|
||||
quantity: 2,
|
||||
quantityFulfilled: 2,
|
||||
unitPrice: {
|
||||
gross: {
|
||||
amount: 9.99,
|
||||
currency: "USD",
|
||||
__typename: "Money"
|
||||
},
|
||||
net: {
|
||||
amount: 9.99,
|
||||
currency: "USD",
|
||||
__typename: "Money"
|
||||
},
|
||||
__typename: "TaxedMoney"
|
||||
},
|
||||
thumbnail: {
|
||||
url:
|
||||
"http://localhost:8000/media/__sized__/products/saleor-digital-03_2-thumbnail-255x255.png",
|
||||
__typename: "Image"
|
||||
},
|
||||
__typename: "OrderLine"
|
||||
},
|
||||
__typename: "FulfillmentLine"
|
||||
},
|
||||
{
|
||||
id: "RnVsZmlsbG1lbnRMaW5lOjMz",
|
||||
quantity: 1,
|
||||
orderLine: {
|
||||
id: "T3JkZXJMaW5lOjQ3",
|
||||
isShippingRequired: true,
|
||||
variant: {
|
||||
id: "UHJvZHVjdFZhcmlhbnQ6Mjg2",
|
||||
quantityAvailable: 50,
|
||||
__typename: "ProductVariant"
|
||||
},
|
||||
productName: "T-shirt",
|
||||
productSku: "29810068",
|
||||
quantity: 3,
|
||||
quantityFulfilled: 1,
|
||||
unitPrice: {
|
||||
gross: {
|
||||
amount: 2.5,
|
||||
currency: "USD",
|
||||
__typename: "Money"
|
||||
},
|
||||
net: {
|
||||
amount: 2.5,
|
||||
currency: "USD",
|
||||
__typename: "Money"
|
||||
},
|
||||
__typename: "TaxedMoney"
|
||||
},
|
||||
thumbnail: {
|
||||
url:
|
||||
"http://localhost:8000/media/__sized__/products/saleordemoproduct_cl_boot06_1-thumbnail-255x255.png",
|
||||
__typename: "Image"
|
||||
},
|
||||
__typename: "OrderLine"
|
||||
},
|
||||
__typename: "FulfillmentLine"
|
||||
}
|
||||
];
|
||||
|
||||
const mergedLines = mergeRepeatedOrderLines(lines);
|
||||
|
||||
expect(mergedLines).toHaveLength(2);
|
||||
expect(
|
||||
mergedLines.find(
|
||||
fulfillmentLine => fulfillmentLine.orderLine.id === "T3JkZXJMaW5lOjQ1"
|
||||
).quantity
|
||||
).toBe(2);
|
||||
});
|
||||
});
|
77
src/orders/utils/data.ts
Normal file
77
src/orders/utils/data.ts
Normal file
|
@ -0,0 +1,77 @@
|
|||
import { IMoney, subtractMoney } from "@saleor/components/Money";
|
||||
import { FormsetData } from "@saleor/hooks/useFormset";
|
||||
|
||||
import { OrderDetails_order_fulfillments_lines } from "../types/OrderDetails";
|
||||
import {
|
||||
OrderRefundData_order,
|
||||
OrderRefundData_order_fulfillments,
|
||||
OrderRefundData_order_lines
|
||||
} from "../types/OrderRefundData";
|
||||
|
||||
export type OrderWithTotalAndTotalCaptured = Pick<
|
||||
OrderRefundData_order,
|
||||
"total" | "totalCaptured"
|
||||
>;
|
||||
|
||||
export function getPreviouslyRefundedPrice(
|
||||
order: OrderWithTotalAndTotalCaptured
|
||||
): IMoney {
|
||||
return (
|
||||
order?.totalCaptured &&
|
||||
order?.total?.gross &&
|
||||
subtractMoney(order?.totalCaptured, order?.total?.gross)
|
||||
);
|
||||
}
|
||||
|
||||
export function getRefundedLinesPriceSum(
|
||||
lines: OrderRefundData_order_lines[],
|
||||
refundedProductQuantities: FormsetData<null, string>
|
||||
): number {
|
||||
return lines?.reduce((sum, line) => {
|
||||
const refundedLine = refundedProductQuantities.find(
|
||||
refundedLine => refundedLine.id === line.id
|
||||
);
|
||||
return sum + line.unitPrice.gross.amount * Number(refundedLine?.value || 0);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
export function getAllFulfillmentLinesPriceSum(
|
||||
fulfillments: OrderRefundData_order_fulfillments[],
|
||||
refundedFulfilledProductQuantities: FormsetData<null, string>
|
||||
): number {
|
||||
return fulfillments?.reduce((sum, fulfillment) => {
|
||||
const fulfilmentLinesSum = fulfillment?.lines.reduce((sum, line) => {
|
||||
const refundedLine = refundedFulfilledProductQuantities.find(
|
||||
refundedLine => refundedLine.id === line.id
|
||||
);
|
||||
return (
|
||||
sum +
|
||||
line.orderLine.unitPrice.gross.amount * Number(refundedLine?.value || 0)
|
||||
);
|
||||
}, 0);
|
||||
return sum + fulfilmentLinesSum;
|
||||
}, 0);
|
||||
}
|
||||
|
||||
export function mergeRepeatedOrderLines(
|
||||
fulfillmentLines: OrderDetails_order_fulfillments_lines[]
|
||||
) {
|
||||
return fulfillmentLines.reduce((prev, curr) => {
|
||||
const existingOrderLineIndex = prev.findIndex(
|
||||
prevLine => prevLine.orderLine.id === curr.orderLine.id
|
||||
);
|
||||
|
||||
if (existingOrderLineIndex === -1) {
|
||||
prev.push(curr);
|
||||
} else {
|
||||
const existingOrderLine = prev[existingOrderLineIndex];
|
||||
|
||||
prev[existingOrderLineIndex] = {
|
||||
...existingOrderLine,
|
||||
quantity: existingOrderLine.quantity + curr.quantity
|
||||
};
|
||||
}
|
||||
|
||||
return prev;
|
||||
}, Array<OrderDetails_order_fulfillments_lines>());
|
||||
}
|
|
@ -19,7 +19,6 @@ import { OrderLineDelete } from "../../types/OrderLineDelete";
|
|||
import { OrderLinesAdd } from "../../types/OrderLinesAdd";
|
||||
import { OrderLineUpdate } from "../../types/OrderLineUpdate";
|
||||
import { OrderMarkAsPaid } from "../../types/OrderMarkAsPaid";
|
||||
import { OrderRefund } from "../../types/OrderRefund";
|
||||
import { OrderShippingMethodUpdate } from "../../types/OrderShippingMethodUpdate";
|
||||
import { OrderUpdate } from "../../types/OrderUpdate";
|
||||
import { OrderVoid } from "../../types/OrderVoid";
|
||||
|
@ -42,7 +41,6 @@ interface OrderDetailsMessages {
|
|||
handleOrderMarkAsPaid: (data: OrderMarkAsPaid) => void;
|
||||
handleOrderVoid: (data: OrderVoid) => void;
|
||||
handlePaymentCapture: (data: OrderCapture) => void;
|
||||
handlePaymentRefund: (data: OrderRefund) => void;
|
||||
handleShippingMethodUpdate: (data: OrderShippingMethodUpdate) => void;
|
||||
handleUpdate: (data: OrderUpdate) => void;
|
||||
handleInvoiceGeneratePending: (data: InvoiceRequest) => void;
|
||||
|
@ -80,18 +78,6 @@ export const OrderDetailsMessages: React.FC<OrderDetailsMessages> = ({
|
|||
closeModal();
|
||||
}
|
||||
};
|
||||
const handlePaymentRefund = (data: OrderRefund) => {
|
||||
const errs = data.orderRefund?.errors;
|
||||
if (errs.length === 0) {
|
||||
pushMessage({
|
||||
status: "success",
|
||||
text: intl.formatMessage({
|
||||
defaultMessage: "Payment successfully refunded"
|
||||
})
|
||||
});
|
||||
closeModal();
|
||||
}
|
||||
};
|
||||
const handleOrderMarkAsPaid = (data: OrderMarkAsPaid) => {
|
||||
const errs = data.orderMarkAsPaid?.errors;
|
||||
if (errs.length === 0) {
|
||||
|
@ -313,7 +299,6 @@ export const OrderDetailsMessages: React.FC<OrderDetailsMessages> = ({
|
|||
handleOrderMarkAsPaid,
|
||||
handleOrderVoid,
|
||||
handlePaymentCapture,
|
||||
handlePaymentRefund,
|
||||
handleShippingMethodUpdate,
|
||||
handleUpdate
|
||||
});
|
||||
|
|
|
@ -49,6 +49,7 @@ import {
|
|||
orderDraftListUrl,
|
||||
orderFulfillUrl,
|
||||
orderListUrl,
|
||||
orderRefundUrl,
|
||||
orderUrl,
|
||||
OrderUrlDialog,
|
||||
OrderUrlQueryParams
|
||||
|
@ -156,7 +157,6 @@ export const OrderDetails: React.FC<OrderDetailsProps> = ({ id, params }) => {
|
|||
onOrderCancel={orderMessages.handleOrderCancel}
|
||||
onOrderVoid={orderMessages.handleOrderVoid}
|
||||
onPaymentCapture={orderMessages.handlePaymentCapture}
|
||||
onPaymentRefund={orderMessages.handlePaymentRefund}
|
||||
onUpdate={orderMessages.handleUpdate}
|
||||
onDraftUpdate={orderMessages.handleDraftUpdate}
|
||||
onShippingMethodUpdate={
|
||||
|
@ -199,7 +199,6 @@ export const OrderDetails: React.FC<OrderDetailsProps> = ({ id, params }) => {
|
|||
orderLineDelete,
|
||||
orderLineUpdate,
|
||||
orderPaymentCapture,
|
||||
orderPaymentRefund,
|
||||
orderVoid,
|
||||
orderShippingMethodUpdate,
|
||||
orderUpdate,
|
||||
|
@ -281,7 +280,7 @@ export const OrderDetails: React.FC<OrderDetailsProps> = ({ id, params }) => {
|
|||
}
|
||||
onPaymentCapture={() => openModal("capture")}
|
||||
onPaymentVoid={() => openModal("void")}
|
||||
onPaymentRefund={() => openModal("refund")}
|
||||
onPaymentRefund={() => navigate(orderRefundUrl(id))}
|
||||
onProductClick={id => () => navigate(productUrl(id))}
|
||||
onBillingAddressEdit={() =>
|
||||
openModal("edit-billing-address")
|
||||
|
@ -371,7 +370,6 @@ export const OrderDetails: React.FC<OrderDetailsProps> = ({ id, params }) => {
|
|||
}
|
||||
initial={order?.total.gross.amount}
|
||||
open={params.action === "capture"}
|
||||
variant="capture"
|
||||
onClose={closeModal}
|
||||
onSubmit={variables =>
|
||||
orderPaymentCapture.mutate({
|
||||
|
@ -380,23 +378,6 @@ export const OrderDetails: React.FC<OrderDetailsProps> = ({ id, params }) => {
|
|||
})
|
||||
}
|
||||
/>
|
||||
<OrderPaymentDialog
|
||||
confirmButtonState={orderPaymentRefund.opts.status}
|
||||
errors={
|
||||
orderPaymentRefund.opts.data?.orderRefund.errors ||
|
||||
[]
|
||||
}
|
||||
initial={order?.total.gross.amount}
|
||||
open={params.action === "refund"}
|
||||
variant="refund"
|
||||
onClose={closeModal}
|
||||
onSubmit={variables =>
|
||||
orderPaymentRefund.mutate({
|
||||
...variables,
|
||||
id
|
||||
})
|
||||
}
|
||||
/>
|
||||
<OrderFulfillmentCancelDialog
|
||||
confirmButtonState={
|
||||
orderFulfillmentCancel.opts.status
|
||||
|
|
157
src/orders/views/OrderRefund/OrderRefund.tsx
Normal file
157
src/orders/views/OrderRefund/OrderRefund.tsx
Normal file
|
@ -0,0 +1,157 @@
|
|||
import useNavigator from "@saleor/hooks/useNavigator";
|
||||
import useNotifier from "@saleor/hooks/useNotifier";
|
||||
import OrderRefundPage from "@saleor/orders/components/OrderRefundPage";
|
||||
import {
|
||||
OrderRefundAmountCalculationMode,
|
||||
OrderRefundSubmitData,
|
||||
OrderRefundType
|
||||
} from "@saleor/orders/components/OrderRefundPage/form";
|
||||
import {
|
||||
useOrderFulfillmentRefundProductsMutation,
|
||||
useOrderRefundMutation
|
||||
} from "@saleor/orders/mutations";
|
||||
import { useOrderRefundData } from "@saleor/orders/queries";
|
||||
import { orderUrl } from "@saleor/orders/urls";
|
||||
import React from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
|
||||
const getAutomaticallyCalculatedProductsRefundInput = (
|
||||
formData: OrderRefundSubmitData
|
||||
) => ({
|
||||
fulfillmentLines: formData.refundedFulfilledProductQuantities
|
||||
.filter(line => line.value !== "0")
|
||||
.map(line => ({
|
||||
fulfillmentLineId: line.id,
|
||||
quantity: Number(line.value)
|
||||
})),
|
||||
includeShippingCosts: formData.refundShipmentCosts,
|
||||
orderLines: formData.refundedProductQuantities
|
||||
.filter(line => line.value !== "0")
|
||||
.map(line => ({
|
||||
orderLineId: line.id,
|
||||
quantity: Number(line.value)
|
||||
}))
|
||||
});
|
||||
const getManuallySetProductsRefundInput = (
|
||||
formData: OrderRefundSubmitData
|
||||
) => ({
|
||||
amountToRefund: formData.amount,
|
||||
fulfillmentLines: formData.refundedFulfilledProductQuantities
|
||||
.filter(line => line.value !== "0")
|
||||
.map(line => ({
|
||||
fulfillmentLineId: line.id,
|
||||
quantity: Number(line.value)
|
||||
})),
|
||||
includeShippingCosts: formData.refundShipmentCosts,
|
||||
orderLines: formData.refundedProductQuantities
|
||||
.filter(line => line.value !== "0")
|
||||
.map(line => ({
|
||||
orderLineId: line.id,
|
||||
quantity: Number(line.value)
|
||||
}))
|
||||
});
|
||||
|
||||
interface OrderRefundProps {
|
||||
orderId: string;
|
||||
}
|
||||
|
||||
const OrderRefund: React.FC<OrderRefundProps> = ({ orderId }) => {
|
||||
const navigate = useNavigator();
|
||||
const notify = useNotifier();
|
||||
const intl = useIntl();
|
||||
|
||||
const { data, loading } = useOrderRefundData({
|
||||
displayLoader: true,
|
||||
variables: {
|
||||
orderId
|
||||
}
|
||||
});
|
||||
const [refundOrder, refundOrderOpts] = useOrderRefundMutation({
|
||||
onCompleted: data => {
|
||||
if (data.orderRefund.errors.length === 0) {
|
||||
navigate(orderUrl(orderId), true);
|
||||
notify({
|
||||
status: "success",
|
||||
text: intl.formatMessage({
|
||||
defaultMessage: "Refunded Items",
|
||||
description: "order refunded success message"
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
const [
|
||||
refundOrderFulfillmentProducts,
|
||||
refundOrderFulfillmentProductsOpts
|
||||
] = useOrderFulfillmentRefundProductsMutation({
|
||||
onCompleted: data => {
|
||||
if (data.orderFulfillmentRefundProducts.errors.length === 0) {
|
||||
navigate(orderUrl(orderId), true);
|
||||
notify({
|
||||
status: "success",
|
||||
text: intl.formatMessage({
|
||||
defaultMessage: "Refunded Items",
|
||||
description: "order refunded success message"
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const handleSubmitMiscellaneousRefund = async (
|
||||
formData: OrderRefundSubmitData
|
||||
) => {
|
||||
const response = await refundOrder({
|
||||
variables: {
|
||||
amount: formData.amount,
|
||||
id: orderId
|
||||
}
|
||||
});
|
||||
|
||||
return response.errors || [];
|
||||
};
|
||||
|
||||
const handleSubmitProductsRefund = async (
|
||||
formData: OrderRefundSubmitData
|
||||
) => {
|
||||
const input =
|
||||
formData.amountCalculationMode ===
|
||||
OrderRefundAmountCalculationMode.AUTOMATIC
|
||||
? getAutomaticallyCalculatedProductsRefundInput(formData)
|
||||
: getManuallySetProductsRefundInput(formData);
|
||||
|
||||
const response = await refundOrderFulfillmentProducts({
|
||||
variables: {
|
||||
input,
|
||||
order: orderId
|
||||
}
|
||||
});
|
||||
|
||||
return response.errors || [];
|
||||
};
|
||||
|
||||
const handleSubmit = async (formData: OrderRefundSubmitData) =>
|
||||
formData.type === OrderRefundType.MISCELLANEOUS
|
||||
? handleSubmitMiscellaneousRefund(formData)
|
||||
: handleSubmitProductsRefund(formData);
|
||||
|
||||
return (
|
||||
<OrderRefundPage
|
||||
order={data?.order}
|
||||
disabled={
|
||||
loading ||
|
||||
refundOrderOpts.loading ||
|
||||
refundOrderFulfillmentProductsOpts.loading
|
||||
}
|
||||
errors={[
|
||||
...(refundOrderOpts.data?.orderRefund.errors || []),
|
||||
...(refundOrderFulfillmentProductsOpts.data
|
||||
?.orderFulfillmentRefundProducts.errors || [])
|
||||
]}
|
||||
onSubmit={handleSubmit}
|
||||
onBack={() => navigate(orderUrl(orderId))}
|
||||
/>
|
||||
);
|
||||
};
|
||||
OrderRefund.displayName = "OrderRefund";
|
||||
export default OrderRefund;
|
2
src/orders/views/OrderRefund/index.ts
Normal file
2
src/orders/views/OrderRefund/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
|||
export * from "./OrderRefund";
|
||||
export { default } from "./OrderRefund";
|
|
@ -67,7 +67,6 @@ export interface PageCreate_pageCreate_page_pageType {
|
|||
id: string;
|
||||
name: string;
|
||||
attributes: (PageCreate_pageCreate_page_pageType_attributes | null)[] | null;
|
||||
message: string | null;
|
||||
}
|
||||
|
||||
export interface PageCreate_pageCreate_page_metadata {
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -10,5 +10,9 @@ const order = orderFixture("");
|
|||
storiesOf("Orders / OrderHistory", module)
|
||||
.addDecorator(Decorator)
|
||||
.add("default", () => (
|
||||
<OrderHistory onNoteAdd={undefined} history={order.events} />
|
||||
<OrderHistory
|
||||
onNoteAdd={undefined}
|
||||
orderCurrency={order.total.gross.currency}
|
||||
history={order.events}
|
||||
/>
|
||||
));
|
||||
|
|
|
@ -13,23 +13,19 @@ const props: OrderPaymentDialogProps = {
|
|||
initial: 0,
|
||||
onClose: () => undefined,
|
||||
onSubmit: () => undefined,
|
||||
open: true,
|
||||
variant: "capture"
|
||||
open: true
|
||||
};
|
||||
|
||||
storiesOf("Orders / OrderPaymentDialog", module)
|
||||
.addDecorator(Decorator)
|
||||
.add("capture payment", () => <OrderPaymentDialog {...props} />)
|
||||
.add("refund payment", () => (
|
||||
<OrderPaymentDialog {...props} variant="refund" />
|
||||
))
|
||||
.add("errors", () => (
|
||||
<OrderPaymentDialog
|
||||
{...props}
|
||||
errors={[
|
||||
{
|
||||
__typename: "OrderError",
|
||||
code: OrderErrorCode.CANNOT_REFUND,
|
||||
code: OrderErrorCode.CAPTURE_INACTIVE_PAYMENT,
|
||||
field: null
|
||||
},
|
||||
{
|
||||
|
@ -38,6 +34,5 @@ storiesOf("Orders / OrderPaymentDialog", module)
|
|||
field: "payment"
|
||||
}
|
||||
]}
|
||||
variant="refund"
|
||||
/>
|
||||
));
|
||||
|
|
|
@ -17,6 +17,7 @@ export enum AccountErrorCode {
|
|||
DELETE_SUPERUSER_ACCOUNT = "DELETE_SUPERUSER_ACCOUNT",
|
||||
DUPLICATED_INPUT_ITEM = "DUPLICATED_INPUT_ITEM",
|
||||
GRAPHQL_ERROR = "GRAPHQL_ERROR",
|
||||
INACTIVE = "INACTIVE",
|
||||
INVALID = "INVALID",
|
||||
INVALID_CREDENTIALS = "INVALID_CREDENTIALS",
|
||||
INVALID_PASSWORD = "INVALID_PASSWORD",
|
||||
|
@ -454,6 +455,7 @@ export enum FileTypesEnum {
|
|||
export enum FulfillmentStatus {
|
||||
CANCELED = "CANCELED",
|
||||
FULFILLED = "FULFILLED",
|
||||
REFUNDED = "REFUNDED",
|
||||
}
|
||||
|
||||
export enum InvoiceErrorCode {
|
||||
|
@ -567,6 +569,7 @@ export enum OrderErrorCode {
|
|||
CANNOT_CANCEL_ORDER = "CANNOT_CANCEL_ORDER",
|
||||
CANNOT_DELETE = "CANNOT_DELETE",
|
||||
CANNOT_REFUND = "CANNOT_REFUND",
|
||||
CANNOT_REFUND_FULFILLMENT_LINE = "CANNOT_REFUND_FULFILLMENT_LINE",
|
||||
CAPTURE_INACTIVE_PAYMENT = "CAPTURE_INACTIVE_PAYMENT",
|
||||
CHANNEL_INACTIVE = "CHANNEL_INACTIVE",
|
||||
DUPLICATED_INPUT_ITEM = "DUPLICATED_INPUT_ITEM",
|
||||
|
@ -574,6 +577,7 @@ export enum OrderErrorCode {
|
|||
GRAPHQL_ERROR = "GRAPHQL_ERROR",
|
||||
INSUFFICIENT_STOCK = "INSUFFICIENT_STOCK",
|
||||
INVALID = "INVALID",
|
||||
INVALID_REFUND_QUANTITY = "INVALID_REFUND_QUANTITY",
|
||||
NOT_AVAILABLE_IN_CHANNEL = "NOT_AVAILABLE_IN_CHANNEL",
|
||||
NOT_EDITABLE = "NOT_EDITABLE",
|
||||
NOT_FOUND = "NOT_FOUND",
|
||||
|
@ -613,6 +617,7 @@ export enum OrderEventsEnum {
|
|||
EXTERNAL_SERVICE_NOTIFICATION = "EXTERNAL_SERVICE_NOTIFICATION",
|
||||
FULFILLMENT_CANCELED = "FULFILLMENT_CANCELED",
|
||||
FULFILLMENT_FULFILLED_ITEMS = "FULFILLMENT_FULFILLED_ITEMS",
|
||||
FULFILLMENT_REFUNDED = "FULFILLMENT_REFUNDED",
|
||||
FULFILLMENT_RESTOCKED_ITEMS = "FULFILLMENT_RESTOCKED_ITEMS",
|
||||
INVOICE_GENERATED = "INVOICE_GENERATED",
|
||||
INVOICE_REQUESTED = "INVOICE_REQUESTED",
|
||||
|
@ -1351,6 +1356,24 @@ export interface OrderLineInput {
|
|||
quantity: number;
|
||||
}
|
||||
|
||||
export interface OrderRefundFulfillmentLineInput {
|
||||
fulfillmentLineId?: string | null;
|
||||
quantity: number;
|
||||
}
|
||||
|
||||
export interface OrderRefundLineInput {
|
||||
orderLineId?: string | null;
|
||||
quantity: number;
|
||||
}
|
||||
|
||||
export interface OrderRefundProductsInput {
|
||||
orderLines?: OrderRefundLineInput[] | null;
|
||||
fulfillmentLines?: OrderRefundFulfillmentLineInput[] | null;
|
||||
notifyCustomer?: boolean | null;
|
||||
amountToRefund?: any | null;
|
||||
includeShippingCosts?: boolean | null;
|
||||
}
|
||||
|
||||
export interface OrderSettingsUpdateInput {
|
||||
automaticallyConfirmAllNewOrders: boolean;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue