projects/congarevenuecloud/elements/src/lib/price-summary/price-summary.component.ts
This component is a work in progress.
The price summary component displays the total price, promotion(s) applied, tax, sub total and action button(s) as per the need.
import { PriceSummaryModule } from '@congarevenuecloud/elements';
@NgModule({
imports: [PriceSummaryModule, ...]
})
export class AppModule {}
```typescript
<apt-price-summary
[record]="cart"
[form]="form"
[spinner]="isLoading"
[page]="'checkout'"
(onSubmitOrder)="handleClick()"
(onRequestQuote)="handleClick()"
></apt-price-summary>
OnInit
OnDestroy
OnChanges
selector | apt-price-summary |
styleUrls | ./price-summary.component.scss |
templateUrl | ./price-summary.component.html |
Properties |
Methods |
Inputs |
Outputs |
constructor(storefrontService: StorefrontService, userService: UserService, crService: ConstraintRuleService, modalService: BsModalService, quoteService: QuoteService, cartService: CartService, exceptionService: ExceptionService, router: Router, accountService: AccountService, orderService: OrderService)
|
|||||||||||||||||||||||||||||||||
Parameters :
|
disabled |
Type : boolean
|
Default value : false
|
Flag defines whether the actions on price summary component should be disabled or not. |
disableSubmit |
Type : boolean
|
Default value : false
|
Flag to disable the submit button. |
form |
Type : NgForm
|
The input form to validate the parent component's form on submit |
loading |
Type : boolean
|
Default value : false
|
Flag to set the loading spinner active |
page |
Type : "checkout" | "create-proposal" | "quotes" | "orders" | "paymentForOrder" | "carts" | string
|
The input page to manage UI element(s)'s visibility (show/hide) based on the page where this component is being used |
paymentState |
Type : "PONUMBER" | "INVOICE" | "PAYNOW" | string
|
Payment state such as Card and Invoice |
readonly |
Type : boolean
|
Default value : false
|
Flag to check if this component should be read only. |
record |
Type : Cart | Quote | Order
|
The input record to display the price summary . Can be of type Cart, Quote and Order |
showCaptcha |
Type : boolean
|
Default value : false
|
Flag to enable captcha verification on checkout pages in price summary component. |
showStatus |
Type : boolean
|
Default value : false
|
Flag to show the payment status on the summary card. |
showTotalsOnly |
Type : boolean
|
Default value : false
|
Flag defines whether the prices should be shown in detail or not. By default it is always set to false. When the flag is set to true only totals such as total price and total promotion(s) will be shown Else displays all of the price breaks such as total price, promotion(s) applied, sub total etc. |
onFinalizeQuote |
Type : EventEmitter<any>
|
Event emitter fired when the Finalize and Submit button is pressed. |
onHidePanel |
Type : EventEmitter<string>
|
Event emitter fired when the close button is clicked. |
onPaymentRequest |
Type : EventEmitter<any>
|
Event emitter fired when the make payment button is pressed. |
onRequestQuote |
Type : EventEmitter<any>
|
Event emitter fired when the request quote button is pressed. |
onShowCaptcha |
Type : EventEmitter<any>
|
Event emitter fired when the request quote button is pressed. |
onShowPanel |
Type : EventEmitter<string>
|
Event emitter fired when the view details button is clicked. |
onSubmitOrder |
Type : EventEmitter<string>
|
Event emitter fired when the order is summited. |
confirmOrderChanges |
confirmOrderChanges()
|
Function used to save the changes after editing the order, It will calculate the tax first and convert cart to order.
Returns :
void
|
captchaVerified |
Type : boolean
|
Default value : false
|
cartTotalModal |
Type : BsModalRef
|
CartTotalTemplate |
Type : TemplateRef<any>
|
Decorators :
@ViewChild('CartTotalTemplate')
|
loadCaptcha |
Type : boolean
|
Default value : false
|
taxSubscription |
Type : Subscription
|
<ng-container *ngIf="view$ | async as view">
<div class="card" *ngIf="record">
<div class="card-header border-bottom px-3 py-2">
<div class="d-flex justify-content-between py-2">
<h5 class="card-title m-0">{{'DETAILS.PRICE_SUMMARY' | translate }}</h5>
<button class="py-0 btn btn-link btn-sm px-0 align-self-center"
*ngIf="showTotalsOnly && view?.lineItemCount > 0" type="button" data-toggle="collapse"
data-target="#navbarSupportedContent" (click)="showPanel()">
{{ "COMMON.VIEW_DETAILS" | translate }}
</button>
<div class="flex-row-reverse" *ngIf="!showTotalsOnly && page ==='carts'">
<button type="button" class="close pull-right" aria-label="Close" (click)="hidePanel()">
<span aria-hidden="true">×</span>
</button>
</div>
</div>
</div>
<div class="card-body" [class.pb-0]="page === 'carts'">
<ng-container
*ngIf="record?.Items?.length > 0 || record?.OrderLineItems?.length > 0 || record?.LineItems?.length > 0; else showMessage">
<div class="d-flex justify-content-between" *ngIf="!record?.SummaryGroups && !showTotalsOnly">
<label> {{'MANAGE_CART.CART_SUMMARY.SUB_TOTAL' | translate }} </label>
<!-- To Do: Need to revist when subtotal for order and quote is fetched from API.-->
<apt-price [record]="record" type="listExtended"></apt-price>
</div>
<!-- Promotion field for Manage Cart & Checkout pages which does require storefront.EnablePromotions check -->
<div *ngIf="view?.enablePromotions && view?.totalPromotions"
class="d-flex justify-content-between mt-1 text-muted small">
<label class="text-truncate pt-1"> {{'MANAGE_CART.CART_SUMMARY.PROMOTIONS_APPLIED' | translate }}
</label>
<span>{{view?.totalPromotions | localCurrency | async}}</span>
</div>
<div *ngIf="record?.SummaryGroups; else displayPrice">
<ng-container *ngFor="let item of record?.SummaryGroups">
<div class="d-flex justify-content-between mt-1 text-muted small"
*ngIf="item?.Name !== 'Grand Total' && !showTotalsOnly; else grandTotal">
<label class="text-truncate pt-1" tooltip="{{item?.Name}}"> {{item?.Name}}</label>
<span>{{item?.NetPrice | localCurrency | async}}</span>
</div>
<ng-template #grandTotal>
<hr class="mt-3 mb-2" *ngIf="item?.Name === 'Grand Total'" />
<div class="d-flex justify-content-between align-items-center"
*ngIf="item?.Name === 'Grand Total'" [class.pb-2]="page === 'carts'">
<div class="d-flex align-items-center">
<label> {{'MANAGE_CART.CART_SUMMARY.TOTAL_PRICE' | translate }} </label>
<app-cart-totals-view [readonly]="readonly" [flowName]="view?.storefront?.FlowName"
[summaryGroups]="view?.cartTotal"
[count]="view?.lineItemCount"></app-cart-totals-view>
</div>
<span>
{{item?.NetPrice | localCurrency | async}}
</span>
</div>
</ng-template>
</ng-container>
</div>
<ng-template #displayPrice>
<hr class="mt-3 mb-2" />
<div class="d-flex justify-content-between">
<label> {{'MANAGE_CART.CART_SUMMARY.TOTAL_PRICE' | translate }} </label>
<span *ngIf="record?.OrderAmount; else quoteAmount">
{{record?.OrderAmount?.DisplayValue | localCurrency | async}}
</span>
<ng-template #quoteAmount>
<span id="quoteAmount" *ngIf="record?.Amount; else empty">
{{record?.Amount?.DisplayValue | localCurrency | async}}
</span>
</ng-template>
<ng-template #empty>
<span id="empty">-</span>
</ng-template>
</div>
</ng-template>
<!-- Few pages doesn't require any action button; in that case no need to show <hr> -->
<hr class="m-0" *ngIf="page !== 'quotes' && page !== 'orders'" />
<!-- Action buttons for Manage Cart page -->
<div class="d-flex justify-content-end mt-2 mb-3"
*ngIf="page === 'carts' && !view?.quote?.Id && !view?.order">
<button class="btn btn-link" *ngIf="!readonly" [routerLink]="['/proposals/create']"
[hidden]="view?.loading" data-style="zoom-in"
[disabled]="!(view?.lineItemCount > 0) || view?.hasErrors === true || record?.hasErrors || disabled">
{{'COMMON.REQUEST_QUOTE' | translate }}
</button>
<button class="btn btn-primary btn-raised" *ngIf="!readonly" [routerLink]="['/checkout']"
[ladda]="view?.loading" data-style="zoom-in"
[disabled]="!(view?.lineItemCount > 0) || view?.hasErrors === true || record?.hasErrors || disabled">
{{ 'COMMON.PLACE_ORDER' | translate }}
</button>
<button class="btn btn-primary btn-raised" *ngIf="readonly && record.Status==='New'"
[ladda]="view?.loading" data-style="zoom-in" (click)="activeCart(record)">
{{ 'COMMON.ACTIVATE_CART' | translate }}
</button>
</div>
<div class="d-flex justify-content-end mt-2 mb-3"
*ngIf="page === 'carts' && (view?.quote?.Id || view?.order?.Id) && !readonly">
<button class="btn btn-outline-danger mr-2" (click)="openDiscardChangeModals()"
[hidden]="view?.loading" data-style="zoom-in"
[disabled]="view?.hasErrors === true || record?.hasErrors">
{{'MANAGE_CART.CART_SUMMARY.DISCARD_CHANGES' | translate }}
</button>
<button *ngIf="view?.quote?.Id" class="btn btn-primary btn-raised px-2" (click)="finalizeQuote()"
[ladda]="view?.loading" data-style="zoom-in"
[disabled]="!(view?.lineItemCount > 0) || view?.hasErrors === true || record?.hasErrors">
{{'MANAGE_CART.CART_SUMMARY.FINALIZE_AND_SUBMIT' | translate }}
</button>
<button *ngIf="view?.order?.Id" class="btn btn-primary btn-raised px-2"
(click)="confirmOrderChanges()" [ladda]="view?.loading" data-style="zoom-in"
[disabled]="!(view?.lineItemCount > 0) || view?.hasErrors === true || record?.hasErrors">
{{'COMMON.CONFIRM_CHANGES' | translate }}
</button>
</div>
<!-- Action buttons for Checkout page -->
<div *ngIf="page === 'paymentForOrder'">
<button class="btn btn-primary btn-block btn-raised" [ladda]="view?.loading" data-style="zoom-in"
(click)="submitPayment()">
{{'PAYMENT_METHOD_LABELS.MAKE_PAYMENT' | translate}}
</button>
</div>
<!-- Action buttons for Create Proposal page -->
</ng-container>
<ng-template #showMessage>
<h6 class="d-flex justify-content-center flex-column h-100 text-muted">
{{'COMMON.NO_LINE_ITEMS_MESSAGE' | translate: { record: (record?.ProposalCategory === 'Quote' ||
record?.BusinessObjectType === 'Proposal' ?
'quote' : 'order') } }}</h6>
</ng-template>
</div>
</div>
<ng-template #discardChangesTemplate>
<div class="modal-header d-flex flex-row-reverse px-0 pb-1">
<div class="btn-wrapper d-flex align-items-center">
<button type="button" class="close pull-right close-button" aria-label="Close"
(click)="discardChangesModal.hide()">
<span aria-hidden="true">×</span>
</button>
</div>
</div>
<div class="modal-body bg-white flex-column justify-content-center">
<h4 class="modal-title font-weight-bold pb-3"> {{'MANAGE_CART.DISCARD_CHANGES_MODAL.DISCARD_CHANGES_TITLE' |
translate}}
</h4>
<p>{{'MANAGE_CART.DISCARD_CHANGES_MODAL.DISCARD_CHANGES_Message' | translate}}</p>
<p>{{'MANAGE_CART.DISCARD_CHANGES_MODAL.DISCARD_CHANGES_CONFIRMATION' | translate}}</p>
<div class="d-flex justify-content-end flex-wrap flex-md-nowrap">
<button class="btn btn-link" (click)="discardChangesModal.hide()"> {{ 'COMMON.CANCEL' | translate }}
</button>
<button class="btn btn-primary btn-raised m-2" (click)="onDiscardChanges()" [ladda]="view?.loading"
data-style="zoom-in">
{{ 'MANAGE_CART.DISCARD_CHANGES_MODAL.DISCARD_CHANGES' | translate }} </button>
</div>
</div>
</ng-template>
</ng-container>
./price-summary.component.scss
.btn-wrapper {
column-gap: 1em;
}
p.text-center {
cursor: pointer;
}