Преглед изворни кода

feat(admin-ui): Add detailed promotion & tax info to OrderDetail view

Michael Bromley пре 6 година
родитељ
комит
cd823fe07a

+ 3 - 2
packages/admin-ui/src/app/common/generated-types.ts

@@ -3810,7 +3810,7 @@ export type OrderFragment = ({ __typename?: 'Order' } & Pick<Order, 'id' | 'crea
 
 export type FulfillmentFragment = ({ __typename?: 'Fulfillment' } & Pick<Fulfillment, 'id' | 'createdAt' | 'updatedAt' | 'method' | 'trackingCode'>);
 
-export type OrderDetailFragment = ({ __typename?: 'Order' } & Pick<Order, 'id' | 'createdAt' | 'updatedAt' | 'code' | 'state' | 'active' | 'subTotal' | 'subTotalBeforeTax' | 'totalBeforeTax' | 'currencyCode' | 'shipping' | 'total'> & { customer: Maybe<({ __typename?: 'Customer' } & Pick<Customer, 'id' | 'firstName' | 'lastName'>)>, lines: Array<({ __typename?: 'OrderLine' } & Pick<OrderLine, 'id' | 'unitPrice' | 'unitPriceWithTax' | 'quantity' | 'totalPrice'> & { featuredAsset: Maybe<({ __typename?: 'Asset' } & Pick<Asset, 'preview'>)>, productVariant: ({ __typename?: 'ProductVariant' } & Pick<ProductVariant, 'id' | 'name' | 'sku'>), items: Array<({ __typename?: 'OrderItem' } & Pick<OrderItem, 'id' | 'unitPrice' | 'unitPriceIncludesTax' | 'unitPriceWithTax' | 'taxRate' | 'refundId' | 'cancelled'> & { fulfillment: Maybe<({ __typename?: 'Fulfillment' } & FulfillmentFragment)> })> })>, adjustments: Array<({ __typename?: 'Adjustment' } & AdjustmentFragment)>, shippingMethod: Maybe<({ __typename?: 'ShippingMethod' } & Pick<ShippingMethod, 'id' | 'code' | 'description'>)>, shippingAddress: Maybe<({ __typename?: 'OrderAddress' } & ShippingAddressFragment)>, payments: Maybe<Array<({ __typename?: 'Payment' } & Pick<Payment, 'id' | 'createdAt' | 'transactionId' | 'amount' | 'method' | 'state' | 'metadata'> & { refunds: Array<({ __typename?: 'Refund' } & Pick<Refund, 'id' | 'createdAt' | 'state' | 'items' | 'adjustment' | 'total' | 'paymentId' | 'reason' | 'transactionId' | 'method' | 'metadata'> & { orderItems: Array<({ __typename?: 'OrderItem' } & Pick<OrderItem, 'id'>)> })> })>>, fulfillments: Maybe<Array<({ __typename?: 'Fulfillment' } & FulfillmentFragment)>> });
+export type OrderDetailFragment = ({ __typename?: 'Order' } & Pick<Order, 'id' | 'createdAt' | 'updatedAt' | 'code' | 'state' | 'active' | 'subTotal' | 'subTotalBeforeTax' | 'totalBeforeTax' | 'currencyCode' | 'shipping' | 'shippingWithTax' | 'total'> & { customer: Maybe<({ __typename?: 'Customer' } & Pick<Customer, 'id' | 'firstName' | 'lastName'>)>, lines: Array<({ __typename?: 'OrderLine' } & Pick<OrderLine, 'id' | 'unitPrice' | 'unitPriceWithTax' | 'quantity' | 'totalPrice'> & { featuredAsset: Maybe<({ __typename?: 'Asset' } & Pick<Asset, 'preview'>)>, productVariant: ({ __typename?: 'ProductVariant' } & Pick<ProductVariant, 'id' | 'name' | 'sku'>), adjustments: Array<({ __typename?: 'Adjustment' } & AdjustmentFragment)>, items: Array<({ __typename?: 'OrderItem' } & Pick<OrderItem, 'id' | 'unitPrice' | 'unitPriceIncludesTax' | 'unitPriceWithTax' | 'taxRate' | 'refundId' | 'cancelled'> & { fulfillment: Maybe<({ __typename?: 'Fulfillment' } & FulfillmentFragment)> })> })>, adjustments: Array<({ __typename?: 'Adjustment' } & AdjustmentFragment)>, shippingMethod: Maybe<({ __typename?: 'ShippingMethod' } & Pick<ShippingMethod, 'id' | 'code' | 'description'>)>, shippingAddress: Maybe<({ __typename?: 'OrderAddress' } & ShippingAddressFragment)>, payments: Maybe<Array<({ __typename?: 'Payment' } & Pick<Payment, 'id' | 'createdAt' | 'transactionId' | 'amount' | 'method' | 'state' | 'metadata'> & { refunds: Array<({ __typename?: 'Refund' } & Pick<Refund, 'id' | 'createdAt' | 'state' | 'items' | 'adjustment' | 'total' | 'paymentId' | 'reason' | 'transactionId' | 'method' | 'metadata'> & { orderItems: Array<({ __typename?: 'OrderItem' } & Pick<OrderItem, 'id'>)> })> })>>, fulfillments: Maybe<Array<({ __typename?: 'Fulfillment' } & FulfillmentFragment)>> });
 
 export type GetOrderListQueryVariables = {
   options?: Maybe<OrderListOptions>
@@ -4725,9 +4725,10 @@ export namespace OrderDetail {
   export type Lines = (NonNullable<OrderDetailFragment['lines'][0]>);
   export type FeaturedAsset = (NonNullable<(NonNullable<OrderDetailFragment['lines'][0]>)['featuredAsset']>);
   export type ProductVariant = (NonNullable<OrderDetailFragment['lines'][0]>)['productVariant'];
+  export type Adjustments = AdjustmentFragment;
   export type Items = (NonNullable<(NonNullable<OrderDetailFragment['lines'][0]>)['items'][0]>);
   export type Fulfillment = FulfillmentFragment;
-  export type Adjustments = AdjustmentFragment;
+  export type _Adjustments = AdjustmentFragment;
   export type ShippingMethod = (NonNullable<OrderDetailFragment['shippingMethod']>);
   export type ShippingAddress = ShippingAddressFragment;
   export type Payments = (NonNullable<(NonNullable<OrderDetailFragment['payments']>)[0]>);

+ 4 - 0
packages/admin-ui/src/app/data/definitions/order-definitions.ts

@@ -85,6 +85,9 @@ export const ORDER_DETAIL_FRAGMENT = gql`
                 name
                 sku
             }
+            adjustments {
+                ...Adjustment
+            }
             unitPrice
             unitPriceWithTax
             quantity
@@ -110,6 +113,7 @@ export const ORDER_DETAIL_FRAGMENT = gql`
         totalBeforeTax
         currencyCode
         shipping
+        shippingWithTax
         shippingMethod {
             id
             code

+ 34 - 8
packages/admin-ui/src/app/order/components/order-detail/order-detail.component.html

@@ -68,6 +68,7 @@
                     <td class="align-middle sku">{{ line.productVariant.sku }}</td>
                     <td class="align-middle unit-price">
                         {{ line.unitPriceWithTax / 100 | currency: order.currencyCode }}
+                        <div class="net-price" [title]="'order.net-price' | translate">{{ line.unitPrice / 100 | currency: order.currencyCode }}</div>
                     </td>
                     <td class="align-middle quantity">
                         {{ line.quantity }}
@@ -76,33 +77,58 @@
                     </td>
                     <td class="align-middle total">
                         {{ line.totalPrice / 100 | currency: order.currencyCode }}
+                        <div class="net-price" [title]="'order.net-price' | translate">{{ line.unitPrice / 100 | currency: order.currencyCode }}</div>
+
+                        <ng-container *ngIf="getLinePromotions(line) as promotions">
+                            <vdr-dropdown *ngIf="promotions.length">
+                                <div class="promotions-label" vdrDropdownTrigger>{{ 'order.promotions-applied' | translate }}</div>
+                                <vdr-dropdown-menu>
+                                    <div class="line-promotion" *ngFor="let promotion of getLinePromotions(line)">
+                                        <a class="promotion-name" [routerLink]="getPromotionLink(promotion)">{{ promotion.description }}</a>
+                                        <div class="promotion-amount">{{ promotion.amount / 100 | currency: order.currencyCode }}</div>
+                                    </div>
+                                </vdr-dropdown-menu>
+                            </vdr-dropdown>
+                        </ng-container>
+
                     </td>
                 </tr>
                 <tr class="sub-total">
-                    <td class="left">{{ 'order.sub-total' | translate }}</td>
+                    <td class="left clr-align-middle">{{ 'order.sub-total' | translate }}</td>
                     <td></td>
                     <td></td>
                     <td></td>
                     <td></td>
-                    <td>{{ order.subTotal / 100 | currency: order.currencyCode }}</td>
+                    <td>
+                        {{ order.subTotal / 100 | currency: order.currencyCode }}
+                        <div class="net-price" [title]="'order.net-price' | translate">{{ order.subTotalBeforeTax / 100 | currency: order.currencyCode }}</div>
+                    </td>
                 </tr>
                 <tr class="order-ajustment" *ngFor="let adjustment of order.adjustments">
-                    <td colspan="5" class="left">{{ adjustment.description }}</td>
+                    <td colspan="5" class="left clr-align-middle">
+                        <a [routerLink]="getPromotionLink(adjustment)">{{ adjustment.description }}</a>
+                    </td>
                     <td>{{ adjustment.amount / 100 | currency: order.currencyCode }}</td>
                 </tr>
                 <tr class="shipping">
-                    <td class="left">{{ 'order.shipping' | translate }}</td>
-                    <td>{{ order.shippingMethod?.description }}</td>
+                    <td class="left clr-align-middle">{{ 'order.shipping' | translate }}</td>
+                    <td class="clr-align-middle">{{ order.shippingMethod?.description }}</td>
                     <td colspan="3"></td>
-                    <td>{{ order.shipping / 100 | currency: order.currencyCode }}</td>
+                    <td>
+                        {{ order.shippingWithTax / 100 | currency: order.currencyCode }}
+                        <div class="net-price" [title]="'order.net-price' | translate">{{ order.shipping / 100 | currency: order.currencyCode }}</div>
+                    </td>
                 </tr>
                 <tr class="total">
-                    <td class="left">{{ 'order.total' | translate }}</td>
+                    <td class="left clr-align-middle">{{ 'order.total' | translate }}</td>
                     <td></td>
                     <td></td>
                     <td></td>
                     <td></td>
-                    <td>{{ order.total / 100 | currency: order.currencyCode }}</td>
+                    <td>
+                        {{ order.total / 100 | currency: order.currencyCode }}
+                        <div class="net-price" [title]="'order.net-price' | translate">{{ order.totalBeforeTax / 100 | currency: order.currencyCode }}</div>
+                    </td>
                 </tr>
             </table>
 

+ 21 - 0
packages/admin-ui/src/app/order/components/order-detail/order-detail.component.scss

@@ -23,6 +23,27 @@
     }
 }
 
+.net-price {
+    font-size: 11px;
+    color: $color-grey-400;
+}
+.promotions-label {
+    text-decoration: underline dotted $color-grey-300;
+    font-size: 11px;
+    margin-top: 6px;
+    cursor: pointer;
+    text-transform: lowercase;
+}
+
+.line-promotion {
+    display: flex;
+    justify-content: space-between;
+    padding: 6px 12px;
+    .promotion-amount {
+        margin-left: 12px;
+    }
+}
+
 .order-cards {
     h6 {
         margin-top: 6px;

+ 10 - 0
packages/admin-ui/src/app/order/components/order-detail/order-detail.component.ts

@@ -8,6 +8,7 @@ import { _ } from 'src/app/core/providers/i18n/mark-for-extraction';
 
 import { BaseDetailComponent } from '../../../common/base-detail.component';
 import {
+    AdjustmentType,
     CustomFieldConfig,
     GetOrderHistory,
     Order,
@@ -68,6 +69,15 @@ export class OrderDetailComponent extends BaseDetailComponent<OrderDetail.Fragme
         this.destroy();
     }
 
+    getLinePromotions(line: OrderDetail.Lines) {
+        return line.adjustments.filter(a => a.type === AdjustmentType.PROMOTION);
+    }
+
+    getPromotionLink(promotion: OrderDetail.Adjustments): any[] {
+        const id = promotion.adjustmentSource.split(':')[1];
+        return ['/marketing', 'promotions', id];
+    }
+
     getShippingAddressLines(shippingAddress?: { [key: string]: string }): string[] {
         if (!shippingAddress) {
             return [];

+ 2 - 0
packages/admin-ui/src/i18n-messages/en.json

@@ -443,6 +443,7 @@
     "line-fulfillment-all": "All items fulfilled",
     "line-fulfillment-none": "No items fulfilled",
     "line-fulfillment-partial": "{ count } of { total } items fulfilled",
+    "net-price": "Net price",
     "order-history": "Order history",
     "payment": "Payment",
     "payment-amount": "Payment amount",
@@ -452,6 +453,7 @@
     "payment-to-refund": "Payment to refund",
     "product-name": "Product name",
     "product-sku": "SKU",
+    "promotions-applied": "Promotions applied",
     "quantity": "Quantity",
     "refund": "Refund",
     "refund-adjustment": "Adjustment",