mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
Added Service to Fetch the Availability Date
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
import { TestBed, getTestBed } from '@angular/core/testing';
|
||||
import { CatAvailabilityService } from './cat-availability.service';
|
||||
import { HttpTestingController, HttpClientTestingModule } from '@angular/common/http/testing';
|
||||
import { CAT_SERVICE_ENDPOINT } from './tokens';
|
||||
import { AvailabilityRequestDTO } from './dtos';
|
||||
import { CatServiceValidationError } from './errors';
|
||||
|
||||
|
||||
describe('CatAvailabilityService', () => {
|
||||
const endpoint = 'https://fake-endpoint.de';
|
||||
let injector: TestBed;
|
||||
let service: CatAvailabilityService;
|
||||
let httpMock: HttpTestingController;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [HttpClientTestingModule],
|
||||
providers: [
|
||||
CatAvailabilityService,
|
||||
{ provide: CAT_SERVICE_ENDPOINT, useValue: endpoint }
|
||||
]
|
||||
});
|
||||
|
||||
injector = getTestBed();
|
||||
service = injector.get(CatAvailabilityService);
|
||||
httpMock = injector.get(HttpTestingController);
|
||||
});
|
||||
|
||||
describe('#get', () => {
|
||||
it('should issue a POST request to /ola/availability', () => {
|
||||
service.get([]).subscribe();
|
||||
|
||||
const req = httpMock.expectOne({ method: 'POST', url: `${endpoint}/ola/availability` });
|
||||
});
|
||||
|
||||
it('should have the argument in the request body', () => {
|
||||
const av: AvailabilityRequestDTO[] = [{ ean: '123456789' }];
|
||||
|
||||
service.get(av).subscribe();
|
||||
|
||||
const req = httpMock.expectOne({ method: 'POST', url: `${endpoint}/ola/availability` });
|
||||
|
||||
expect(req.request.body).toBe(av);
|
||||
});
|
||||
|
||||
it('should throw an CatServiceValidationError if the validation fails', () => {
|
||||
const av: AvailabilityRequestDTO[] = [null];
|
||||
|
||||
service.get(av).subscribe(
|
||||
() => { console.log('fsag'); },
|
||||
(error) => {
|
||||
expect(error instanceof CatServiceValidationError).toBeTruthy();
|
||||
}
|
||||
);
|
||||
|
||||
httpMock.expectNone({ method: 'POST', url: `${endpoint}/ola/availability` });
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
39
projects/cat-service/src/lib/cat-availability.service.ts
Normal file
39
projects/cat-service/src/lib/cat-availability.service.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { Injectable, Inject } from '@angular/core';
|
||||
import { AvailabilityRequestDTO, ArticleAvailabilityDTO } from './dtos';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { CAT_AV_SERVICE_ENDPOINT } from './tokens';
|
||||
import { Observable, isObservable, throwError, } from 'rxjs';
|
||||
import { ApiResponse } from './response';
|
||||
import { availabilityRequestValidator } from './validators';
|
||||
import { CatServiceValidationError } from './errors';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class CatAvailabilityService {
|
||||
|
||||
endpoint = '';
|
||||
|
||||
constructor(
|
||||
private http: HttpClient,
|
||||
@Inject(CAT_AV_SERVICE_ENDPOINT) endpoint: string | Observable<string>
|
||||
) {
|
||||
if (isObservable(endpoint)) {
|
||||
endpoint.subscribe(e => this.endpoint = e);
|
||||
} else {
|
||||
this.endpoint = endpoint;
|
||||
}
|
||||
}
|
||||
|
||||
get(req: AvailabilityRequestDTO[]): Observable<ApiResponse<ArticleAvailabilityDTO[]>> {
|
||||
|
||||
for (const result of req.map(item => availabilityRequestValidator(item))) {
|
||||
if (!result.valid) {
|
||||
return throwError(new CatServiceValidationError(result));
|
||||
}
|
||||
}
|
||||
|
||||
return this.http.post<ApiResponse<ArticleAvailabilityDTO[]>>(
|
||||
`${this.endpoint}/ola/availability`,
|
||||
req
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
import { PriceDTO } from './price.dto';
|
||||
import { AvailabilityType } from '../../enums';
|
||||
|
||||
export interface ArticleAvailabilityDTO {
|
||||
/**
|
||||
* Produkt / Artikel PK
|
||||
*/
|
||||
itemId?: number;
|
||||
|
||||
/**
|
||||
* Eindeutige Referenz zur Zuordnung
|
||||
*/
|
||||
requestReference: string;
|
||||
|
||||
/**
|
||||
* EAN
|
||||
*/
|
||||
ean: string;
|
||||
|
||||
/**
|
||||
* Shop Id
|
||||
*/
|
||||
shop?: number;
|
||||
|
||||
/**
|
||||
* Price
|
||||
*/
|
||||
price: PriceDTO;
|
||||
|
||||
/**
|
||||
* Lieferant
|
||||
*/
|
||||
supplier: string;
|
||||
|
||||
/**
|
||||
* Stock Status Code / Meldeschlüssel
|
||||
*/
|
||||
ssc: string;
|
||||
|
||||
/**
|
||||
* Verfügbare Menge
|
||||
*/
|
||||
qty?: number;
|
||||
|
||||
/**
|
||||
* Vorgemerkt
|
||||
*/
|
||||
isPrebooked?: boolean;
|
||||
|
||||
/**
|
||||
* Voraussichtliches Lieferdatum
|
||||
*/
|
||||
at?: Date;
|
||||
|
||||
/**
|
||||
* Alternatives Voraussichtliches Lieferdatum
|
||||
*/
|
||||
altAt?: Date;
|
||||
|
||||
/**
|
||||
* Verfügbarkeitsstatus
|
||||
*/
|
||||
availabilityType: AvailabilityType;
|
||||
|
||||
/**
|
||||
* Rang
|
||||
*/
|
||||
preferred?: number;
|
||||
|
||||
/**
|
||||
* Zeitstemple der Anfrage
|
||||
*/
|
||||
requested?: Date;
|
||||
|
||||
/**
|
||||
* StatusCode der Verfügbarkeitsanfrage
|
||||
*/
|
||||
requestStatusCode: string;
|
||||
|
||||
/**
|
||||
* Beschreibung des StatusCode
|
||||
*/
|
||||
requestMessage: string;
|
||||
}
|
||||
@@ -1,10 +1,12 @@
|
||||
// start:ng42.barrel
|
||||
export * from './article-availability.dto';
|
||||
export * from './availability.dto';
|
||||
export * from './item.dto';
|
||||
export * from './price-value.dto';
|
||||
export * from './price.dto';
|
||||
export * from './product.dto';
|
||||
export * from './shelf-info.dto';
|
||||
export * from './shop.dto';
|
||||
export * from './size.dto';
|
||||
export * from './spec.dto';
|
||||
export * from './stock-info.dto';
|
||||
|
||||
11
projects/cat-service/src/lib/dtos/data/shop.dto.ts
Normal file
11
projects/cat-service/src/lib/dtos/data/shop.dto.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
export interface ShopDTO {
|
||||
/**
|
||||
* PK
|
||||
*/
|
||||
id?: number;
|
||||
|
||||
/**
|
||||
* Name / Bezeichner
|
||||
*/
|
||||
name: string;
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
import { PriceDTO } from '../data';
|
||||
|
||||
export interface AvailabilityRequestDTO {
|
||||
/**
|
||||
* Artikel / Produkt PK
|
||||
*/
|
||||
itemId?: string;
|
||||
|
||||
/**
|
||||
* EAN
|
||||
*/
|
||||
ean?: string;
|
||||
|
||||
/**
|
||||
* Menge / Stück
|
||||
*/
|
||||
qty?: number;
|
||||
|
||||
/**
|
||||
* Bestellzeichen
|
||||
*/
|
||||
orderCode?: string;
|
||||
|
||||
/**
|
||||
* Lieferant
|
||||
*/
|
||||
supplier?: string;
|
||||
|
||||
/**
|
||||
* Bestellung vormerken
|
||||
*/
|
||||
preBook?: boolean;
|
||||
|
||||
/**
|
||||
* Preis
|
||||
*/
|
||||
prive?: PriceDTO;
|
||||
|
||||
/**
|
||||
* Stock Status Code
|
||||
*/
|
||||
ssc?: string;
|
||||
|
||||
/**
|
||||
* Vsl. Lieferdatum
|
||||
*/
|
||||
estimatedShipping?: Date;
|
||||
|
||||
/**
|
||||
* Shop PK
|
||||
*/
|
||||
shopId?: number;
|
||||
|
||||
/**
|
||||
* Zuordnungs-ID
|
||||
*/
|
||||
availabilityReference?: string;
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
// start:ng42.barrel
|
||||
export * from './autocomplete-token.dto';
|
||||
export * from './availability-request.dto';
|
||||
export * from './query-token.dto';
|
||||
// end:ng42.barrel
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
import { CatServiceError } from './cat-service.error';
|
||||
import { ValidationResult } from '../models';
|
||||
|
||||
export class CatServiceValidationError extends CatServiceError {
|
||||
constructor(public result: ValidationResult) {
|
||||
super(result.message);
|
||||
}
|
||||
}
|
||||
7
projects/cat-service/src/lib/errors/cat-service.error.ts
Normal file
7
projects/cat-service/src/lib/errors/cat-service.error.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export class CatServiceError extends Error {
|
||||
|
||||
constructor(message: string) {
|
||||
super(`[cat-service] ${message}`);
|
||||
}
|
||||
|
||||
}
|
||||
5
projects/cat-service/src/lib/errors/index.ts
Normal file
5
projects/cat-service/src/lib/errors/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
// start:ng42.barrel
|
||||
export * from './cat-service-validation.error';
|
||||
export * from './cat-service.error';
|
||||
// end:ng42.barrel
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// start:ng42.barrel
|
||||
export * from './cat-image.service';
|
||||
export * from './cat-availability.service';
|
||||
export * from './cat-search-mock.data';
|
||||
export * from './cat-search-mock.service';
|
||||
export * from './cat-search.service';
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// start:ng42.barrel
|
||||
export * from './dictionary.model';
|
||||
export * from './valiation-result.model';
|
||||
// end:ng42.barrel
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import { StringDictionary } from './dictionary.model';
|
||||
|
||||
export class ValidationResult {
|
||||
private _valid = true;
|
||||
get valid() { return this._valid; }
|
||||
private _message?: string;
|
||||
get message() { return this._message; }
|
||||
private _invalidProperties?: StringDictionary<string>;
|
||||
get invalidProperties() { return this._invalidProperties; }
|
||||
|
||||
setMessage(message: string) {
|
||||
this._message = message;
|
||||
this._valid = false;
|
||||
}
|
||||
|
||||
addPropertyError(proeprty: string, reason: string) {
|
||||
const ip = this.invalidProperties || {};
|
||||
|
||||
ip[proeprty] = reason;
|
||||
|
||||
this._invalidProperties = ip;
|
||||
|
||||
if (this.message == null) {
|
||||
this.setMessage('Invalid property.');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,3 +2,4 @@ import { InjectionToken } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
export const CAT_SERVICE_ENDPOINT = new InjectionToken<string | Observable<string>>('cat:service:endpoint');
|
||||
export const CAT_AV_SERVICE_ENDPOINT = new InjectionToken<string | Observable<string>>('cat:av:service:endpoint');
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import { AvailabilityRequestDTO } from '../dtos';
|
||||
import { ValidationResult, StringDictionary } from '../models';
|
||||
|
||||
export function availabilityRequestValidator(av: AvailabilityRequestDTO): ValidationResult {
|
||||
|
||||
const result = new ValidationResult();
|
||||
|
||||
if (av == null) {
|
||||
result.setMessage('AvailabilityRequestDTO is null or undefined.');
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
4
projects/cat-service/src/lib/validators/index.ts
Normal file
4
projects/cat-service/src/lib/validators/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
// start:ng42.barrel
|
||||
export * from './availability-request.validator';
|
||||
// end:ng42.barrel
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* Public API Surface of cat-service
|
||||
*/
|
||||
export * from './lib/cat-image.service';
|
||||
export * from './lib/cat-availability.service';
|
||||
export * from './lib/cat-search-mock.data';
|
||||
export * from './lib/cat-search-mock.service';
|
||||
export * from './lib/cat-search.service';
|
||||
|
||||
@@ -7,7 +7,7 @@ import { ComponentsModule } from './modules/components.module';
|
||||
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
|
||||
import { BasicAuthorizationInterceptor, BasicAuthorizationOptions } from './core/interceptors';
|
||||
import { SearchResultsComponent } from './components/search-results/search-results.component';
|
||||
import { CatServiceModule, CAT_SERVICE_ENDPOINT, CatSearchService } from 'cat-service';
|
||||
import { CatServiceModule, CAT_SERVICE_ENDPOINT, CatSearchService, CAT_AV_SERVICE_ENDPOINT } from 'cat-service';
|
||||
import { ProductCardComponent } from './components/product-card/product-card.component';
|
||||
import { ConfigService } from './core/services/config.service';
|
||||
import { ProductDetailsComponent } from './components/product-details/product-details.component';
|
||||
@@ -45,7 +45,11 @@ export function _basicAuthorizationInterceptorFactory(conf: ConfigService) {
|
||||
}
|
||||
|
||||
export function _catServiceEndpointProviderFactory(conf: ConfigService) {
|
||||
return conf.select<string>('catService', 'endpoint');
|
||||
return conf.select<string>('catService', 'endpoint', 'catService');
|
||||
}
|
||||
|
||||
export function _catAvServiceEndpointProviderFactory(conf: ConfigService) {
|
||||
return conf.select<string>('catService', 'endpoint', 'avService');
|
||||
}
|
||||
|
||||
export function _feedServiceEndpointProviderFactory(conf: ConfigService) {
|
||||
@@ -79,6 +83,7 @@ export function _feedServiceEndpointProviderFactory(conf: ConfigService) {
|
||||
{ provide: APP_INITIALIZER, useFactory: _configInitializer, multi: true, deps: [ ConfigService ] },
|
||||
{ provide: HTTP_INTERCEPTORS, useFactory: _basicAuthorizationInterceptorFactory, deps: [ConfigService], multi: true },
|
||||
{ provide: CAT_SERVICE_ENDPOINT, useFactory: _catServiceEndpointProviderFactory, deps: [ConfigService] },
|
||||
{ provide: CAT_AV_SERVICE_ENDPOINT, useFactory: _catAvServiceEndpointProviderFactory, deps: [ConfigService] },
|
||||
{ provide: FEED_SERVICE_ENDPOINT, useFactory: _feedServiceEndpointProviderFactory, deps: [ConfigService] },
|
||||
// { provide: CatSearchService, useClass: CatSearchMockService }, // Uncomment if u want to use the CatSearchMockService
|
||||
{ provide: FeedService, useClass: FeedMockService } // Uncomment if u want to use the FeedMockService
|
||||
|
||||
@@ -3,11 +3,15 @@
|
||||
"client": "eu6YYrF3NB4CtxMTwrgC",
|
||||
"password": "rf5f9JUzKW7cjwd6vb6YHv2L2knEZ6m4mNsbpLMF",
|
||||
"endpoints": [
|
||||
"https://catsearch.paragon-data.de"
|
||||
"https://catsearch.paragon-data.de",
|
||||
"https://ava.paragon-data.de"
|
||||
]
|
||||
},
|
||||
"catService": {
|
||||
"endpoint": "https://catsearch.paragon-data.de"
|
||||
"endpoint": {
|
||||
"catService": "https://catsearch.paragon-data.de",
|
||||
"avService": "https://ava.paragon-data.de"
|
||||
}
|
||||
},
|
||||
"feedService": {
|
||||
"endpoint": "https://isa.paragon-data.de"
|
||||
|
||||
Reference in New Issue
Block a user