Skip to content

Commit

Permalink
ReOrder ability (#118)
Browse files Browse the repository at this point in the history
* merge fix

* remove /src/UI/Buyer/.gitIgnore

* remove karma.conf.js

* remove package-lock.json

* remove package.json

* remove readme

* these files were moved

* Feat: Reorder an Order

This is a container component which takes in a order id. validate the line items on the order, then display which items that are invalid and an add to cart button. Use Container because it calls out to the lineItemService to create line items with the valid products.

* Update reorder component to work with breaking changes

Unit test the order-reorder container

* refactor app lineitem service

* updated asked for changes

* Add Unit tests

update the service to throw an error if no idea is there.
  • Loading branch information
Labedlam authored and oliverheywood451 committed Aug 6, 2018
1 parent 38684f0 commit 30c98ad
Show file tree
Hide file tree
Showing 12 changed files with 478 additions and 2 deletions.
4 changes: 2 additions & 2 deletions docs/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Description

- Summary of the change and which issue is fixed.
- Relevant motivation and context.
- Summary of the change and which issue is fixed.
- Relevant motivation and context.
- List any dependencies that are required for this change.
- Reference to related issues

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<button type="button"
class="btn btn-secondary"
(click)="orderReorder()">Reorder</button>
<shared-modal id="Order-Reorder"
modalTitle="Order Reorder">
<div *ngIf="reorderResponse$ | async as reorderResponse">
<div class="alert"
[ngClass]="{'alert-danger': message.classType == 'danger',
'alert-warning': message.classType == 'warning',
'alert-success': message.classType == 'success'}">
<p [innerHTML]='message.string'> </p>
</div>
<shared-lineitem-list-wrapper *ngIf="reorderResponse.InvalidLi.length">
<shared-line-item-card *ngFor="let li of reorderResponse.InvalidLi"
[lineitem]="li"
[productDetails]="li.Product"
readOnly="true">
</shared-line-item-card>
</shared-lineitem-list-wrapper>
<button type="button"
class="btn btn-primary btn-lg btn-block"
[disabled]="!reorderResponse.ValidLi.length || !orderID"
(click)="addToCart()">Add to Cart</button>
</div>
</shared-modal>
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { NO_ERRORS_SCHEMA } from '@angular/core';

import { OrderReorderComponent } from '@app-buyer/order/containers/order-reorder/order-reorder.component.ts';
import {
ModalService,
AppReorderService,
AppLineItemService,
} from '@app-buyer/shared';
import { of } from 'rxjs';

describe('OrderReorderComponent', () => {
let component: OrderReorderComponent;
let fixture: ComponentFixture<OrderReorderComponent>;
let reorderResponse$;
let AppReorderServiceTest = null;

const modalServiceTest = {
open: jasmine.createSpy('open').and.returnValue(of({})),
close: jasmine.createSpy('close'),
};

const AppLineItemServiceTest = {
create: jasmine.createSpy('create').and.returnValue(of({})),
};

beforeEach(async(() => {
AppReorderServiceTest = {
order: jasmine.createSpy('order').and.returnValue(
of({
ValidLi: [{ Product: {}, Quantity: 2 }, { Product: {}, Quantity: 2 }],
InvalidLi: [],
})
),
};
TestBed.configureTestingModule({
declarations: [OrderReorderComponent],
providers: [
{ provide: ModalService, useValue: modalServiceTest },
{ provide: AppReorderService, useValue: AppReorderServiceTest },
{ provide: AppLineItemService, useValue: AppLineItemServiceTest },
],
schemas: [NO_ERRORS_SCHEMA], // Ignore template errors: remove if tests are added to test template
}).compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(OrderReorderComponent);
component = fixture.componentInstance;
component.orderID = 'orderID';
fixture.detectChanges();
});

afterEach(() => {
AppReorderServiceTest = null;
});

it('should create', () => {
expect(component).toBeTruthy();
});

describe('ngOnInit with order Input', () => {
it('should call the OrderReorderService', () => {
component.ngOnInit();
expect(AppReorderServiceTest.order).toHaveBeenCalled();
});
});

describe('ngOnInit with no order Input', () => {
it('should call toastr Error', () => {
component.orderID = null;
fixture.detectChanges();
expect(() => component.ngOnInit()).toThrow(new Error('Needs Order ID'));
});
});

describe('orderReorder', () => {
it('should call the modalService', () => {
component.orderReorder();
expect(modalServiceTest.open).toHaveBeenCalled();
});
});

describe('addToCart', () => {
it('should not call the li service create ', () => {
AppReorderServiceTest.order.and.returnValue(
of({
ValidLi: [],
InvalidLi: [],
})
);
fixture.detectChanges();
component.reorderResponse$ = AppReorderServiceTest.order();
component.ngOnInit();
component.addToCart();
expect(AppLineItemServiceTest.create).not.toHaveBeenCalled();
});

it('should call the li create service the correct amount of times', () => {
AppReorderServiceTest.order.and.returnValue(
of({
ValidLi: [{ Product: {}, Quantity: 2 }, { Product: {}, Quantity: 2 }],
InvalidLi: [],
})
);

reorderResponse$ = AppReorderServiceTest.order();
component.ngOnInit();
component.addToCart();
expect(AppLineItemServiceTest.create).toHaveBeenCalledTimes(2);
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { Component, OnInit, Input, OnDestroy } from '@angular/core';
import { Observable } from 'rxjs';
import { takeWhile, tap } from 'rxjs/operators';

import { forEach as _forEach } from 'lodash';

import {
ModalService,
AppLineItemService,
AppReorderService,
} from '@app-buyer/shared';
import { orderReorderResponse } from '@app-buyer/shared/services/oc-reorder/oc-reorder.interface';

@Component({
selector: 'order-reorder',
templateUrl: './order-reorder.component.html',
styleUrls: ['./order-reorder.component.scss'],
})
export class OrderReorderComponent implements OnInit, OnDestroy {
@Input() orderID: string;
reorderResponse$: Observable<orderReorderResponse>;
modalID = 'Order-Reorder';
alive = true;
message = { string: null, classType: null };

constructor(
private appReorderService: AppReorderService,
private modalService: ModalService,
private appLineItemService: AppLineItemService
) {}

ngOnInit() {
if (this.orderID) {
this.reorderResponse$ = this.appReorderService.order(this.orderID).pipe(
tap((response) => {
this.updateMessage(response);
})
);
} else {
throw new Error('Needs Order ID');
}
}

updateMessage(response: orderReorderResponse): void {
if (response.InvalidLi.length && !response.ValidLi.length) {
this.message.string = `None of the line items on this order are available for reorder.`;
this.message.classType = 'danger';
return;
}
if (response.InvalidLi.length && response.ValidLi.length) {
this.message.string = `<strong>Warning</strong> The following line items are not available for reorder, clicking add to cart will <strong>only</strong> add valid line items.`;
this.message.classType = 'warning';
return;
}
this.message.string = `All line items are valid to reorder`;
this.message.classType = 'success';
}

orderReorder() {
this.modalService.open(this.modalID);
}

addToCart() {
this.reorderResponse$
.pipe(takeWhile(() => this.alive))
.subscribe((reorderResponse) => {
_forEach(reorderResponse.ValidLi, (li) => {
if (!li) return;
this.appLineItemService.create(li.Product, li.Quantity).subscribe();
});
this.modalService.close(this.modalID);
});
}

ngOnDestroy() {
this.alive = false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
<a class="breadcrumb-item link-text"
aria-current="page">{{order.ID}}</a>
</nav>
<order-reorder class="float-right pb-2 mt-2 mb-2"
[orderID]='order.ID'></order-reorder>
<div class="pb-2 mt-4 mb-2">
<h2> <span class="text-muted">Order #:</span> {{order.ID}}</h2>
<small>Submitted on {{order.DateSubmitted | date: 'short'}}</small>
Expand Down
2 changes: 2 additions & 0 deletions src/UI/Buyer/src/app/order/order.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { OrderComponent } from '@app-buyer/order/containers/order/order.componen
import { OrderResolve } from '@app-buyer/order/order.resolve';
import { OrderShipmentsComponent } from '@app-buyer/order/containers/order-shipments/order-shipments.component';
import { ShipmentsResolve } from '@app-buyer/order/shipments.resolve';
import { OrderReorderComponent } from '@app-buyer/order/containers/order-reorder/order-reorder.component';
import { OrderAprovalComponent } from '@app-buyer/order/containers/order-approval/order-approval.component';
import { OrderApprovalDetailsComponent } from './containers/order-approval-details/order-approval-details.component';

Expand All @@ -26,6 +27,7 @@ import { OrderApprovalDetailsComponent } from './containers/order-approval-detai
StatusIconComponent,
OrderComponent,
OrderShipmentsComponent,
OrderReorderComponent,
OrderAprovalComponent,
OrderApprovalDetailsComponent,
],
Expand Down
1 change: 1 addition & 0 deletions src/UI/Buyer/src/app/shared/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export * from '@app-buyer/shared/services/oc-form-error/oc-form-error.service';
export * from '@app-buyer/shared/services/oc-geography/oc-geography.service';
export * from '@app-buyer/shared/services/oc-line-item/oc-line-item.service';
export * from '@app-buyer/shared/services/modal/modal.service';
export * from '@app-buyer/shared/services/oc-reorder/oc-reorder.service';

// validators
export * from '@app-buyer/shared/validators/oc-match-fields/oc-match-fields.validator';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { LineItem } from '@ordercloud/angular-sdk';

export interface orderReorderResponse{
ValidLi: Array<LineItem>,
InvalidLi: Array<LineItem>
}
Loading

0 comments on commit 30c98ad

Please sign in to comment.