283 lines
6.9 KiB
TypeScript
283 lines
6.9 KiB
TypeScript
import { inject, Injectable } from '@angular/core';
|
|
import { HttpClient } from '@angular/common/http';
|
|
import { Observable } from 'rxjs';
|
|
import { environment } from '../../../../environments/environment';
|
|
|
|
export interface AdminFilamentStockRow {
|
|
filamentVariantId: number;
|
|
materialCode: string;
|
|
variantDisplayName: string;
|
|
colorName: string;
|
|
stockSpools: number;
|
|
spoolNetKg: number;
|
|
stockKg: number;
|
|
stockFilamentGrams: number;
|
|
active: boolean;
|
|
}
|
|
|
|
export interface AdminFilamentMaterialType {
|
|
id: number;
|
|
materialCode: string;
|
|
isFlexible: boolean;
|
|
isTechnical: boolean;
|
|
technicalTypeLabel?: string;
|
|
}
|
|
|
|
export interface AdminFilamentVariant {
|
|
id: number;
|
|
materialTypeId: number;
|
|
materialCode: string;
|
|
materialIsFlexible: boolean;
|
|
materialIsTechnical: boolean;
|
|
materialTechnicalTypeLabel?: string;
|
|
variantDisplayName: string;
|
|
colorName: string;
|
|
colorHex?: string;
|
|
finishType?: string;
|
|
brand?: string;
|
|
isMatte: boolean;
|
|
isSpecial: boolean;
|
|
costChfPerKg: number;
|
|
stockSpools: number;
|
|
spoolNetKg: number;
|
|
stockKg: number;
|
|
stockFilamentGrams: number;
|
|
isActive: boolean;
|
|
createdAt: string;
|
|
}
|
|
|
|
export interface AdminUpsertFilamentMaterialTypePayload {
|
|
materialCode: string;
|
|
isFlexible: boolean;
|
|
isTechnical: boolean;
|
|
technicalTypeLabel?: string;
|
|
}
|
|
|
|
export interface AdminUpsertFilamentVariantPayload {
|
|
materialTypeId: number;
|
|
variantDisplayName: string;
|
|
colorName: string;
|
|
colorHex?: string;
|
|
finishType?: string;
|
|
brand?: string;
|
|
isMatte: boolean;
|
|
isSpecial: boolean;
|
|
costChfPerKg: number;
|
|
stockSpools: number;
|
|
spoolNetKg: number;
|
|
isActive: boolean;
|
|
}
|
|
|
|
export interface AdminContactRequest {
|
|
id: string;
|
|
requestType: string;
|
|
customerType: string;
|
|
email: string;
|
|
phone?: string;
|
|
name?: string;
|
|
companyName?: string;
|
|
status: string;
|
|
createdAt: string;
|
|
}
|
|
|
|
export interface AdminContactRequestAttachment {
|
|
id: string;
|
|
originalFilename: string;
|
|
mimeType?: string;
|
|
fileSizeBytes?: number;
|
|
createdAt: string;
|
|
}
|
|
|
|
export interface AdminContactRequestDetail {
|
|
id: string;
|
|
requestType: string;
|
|
customerType: string;
|
|
email: string;
|
|
phone?: string;
|
|
name?: string;
|
|
companyName?: string;
|
|
contactPerson?: string;
|
|
message: string;
|
|
status: string;
|
|
createdAt: string;
|
|
updatedAt: string;
|
|
attachments: AdminContactRequestAttachment[];
|
|
}
|
|
|
|
export interface AdminUpdateContactRequestStatusPayload {
|
|
status: string;
|
|
}
|
|
|
|
export interface AdminQuoteSession {
|
|
id: string;
|
|
status: string;
|
|
materialCode: string;
|
|
createdAt: string;
|
|
expiresAt: string;
|
|
convertedOrderId?: string;
|
|
}
|
|
|
|
export interface AdminQuoteSessionDetailItem {
|
|
id: string;
|
|
originalFilename: string;
|
|
quantity: number;
|
|
printTimeSeconds?: number;
|
|
materialGrams?: number;
|
|
colorCode?: string;
|
|
status: string;
|
|
unitPriceChf: number;
|
|
}
|
|
|
|
export interface AdminQuoteSessionDetail {
|
|
session: {
|
|
id: string;
|
|
status: string;
|
|
materialCode: string;
|
|
setupCostChf?: number;
|
|
supportsEnabled?: boolean;
|
|
notes?: string;
|
|
};
|
|
items: AdminQuoteSessionDetailItem[];
|
|
itemsTotalChf: number;
|
|
shippingCostChf: number;
|
|
globalMachineCostChf: number;
|
|
grandTotalChf: number;
|
|
}
|
|
|
|
@Injectable({
|
|
providedIn: 'root',
|
|
})
|
|
export class AdminOperationsService {
|
|
private readonly http = inject(HttpClient);
|
|
private readonly baseUrl = `${environment.apiUrl}/api/admin`;
|
|
|
|
getFilamentStock(): Observable<AdminFilamentStockRow[]> {
|
|
return this.http.get<AdminFilamentStockRow[]>(
|
|
`${this.baseUrl}/filament-stock`,
|
|
{ withCredentials: true },
|
|
);
|
|
}
|
|
|
|
getFilamentMaterials(): Observable<AdminFilamentMaterialType[]> {
|
|
return this.http.get<AdminFilamentMaterialType[]>(
|
|
`${this.baseUrl}/filaments/materials`,
|
|
{ withCredentials: true },
|
|
);
|
|
}
|
|
|
|
getFilamentVariants(): Observable<AdminFilamentVariant[]> {
|
|
return this.http.get<AdminFilamentVariant[]>(
|
|
`${this.baseUrl}/filaments/variants`,
|
|
{ withCredentials: true },
|
|
);
|
|
}
|
|
|
|
createFilamentMaterial(
|
|
payload: AdminUpsertFilamentMaterialTypePayload,
|
|
): Observable<AdminFilamentMaterialType> {
|
|
return this.http.post<AdminFilamentMaterialType>(
|
|
`${this.baseUrl}/filaments/materials`,
|
|
payload,
|
|
{ withCredentials: true },
|
|
);
|
|
}
|
|
|
|
updateFilamentMaterial(
|
|
materialId: number,
|
|
payload: AdminUpsertFilamentMaterialTypePayload,
|
|
): Observable<AdminFilamentMaterialType> {
|
|
return this.http.put<AdminFilamentMaterialType>(
|
|
`${this.baseUrl}/filaments/materials/${materialId}`,
|
|
payload,
|
|
{ withCredentials: true },
|
|
);
|
|
}
|
|
|
|
createFilamentVariant(
|
|
payload: AdminUpsertFilamentVariantPayload,
|
|
): Observable<AdminFilamentVariant> {
|
|
return this.http.post<AdminFilamentVariant>(
|
|
`${this.baseUrl}/filaments/variants`,
|
|
payload,
|
|
{ withCredentials: true },
|
|
);
|
|
}
|
|
|
|
updateFilamentVariant(
|
|
variantId: number,
|
|
payload: AdminUpsertFilamentVariantPayload,
|
|
): Observable<AdminFilamentVariant> {
|
|
return this.http.put<AdminFilamentVariant>(
|
|
`${this.baseUrl}/filaments/variants/${variantId}`,
|
|
payload,
|
|
{ withCredentials: true },
|
|
);
|
|
}
|
|
|
|
deleteFilamentVariant(variantId: number): Observable<void> {
|
|
return this.http.delete<void>(
|
|
`${this.baseUrl}/filaments/variants/${variantId}`,
|
|
{ withCredentials: true },
|
|
);
|
|
}
|
|
|
|
getContactRequests(): Observable<AdminContactRequest[]> {
|
|
return this.http.get<AdminContactRequest[]>(
|
|
`${this.baseUrl}/contact-requests`,
|
|
{ withCredentials: true },
|
|
);
|
|
}
|
|
|
|
getContactRequestDetail(
|
|
requestId: string,
|
|
): Observable<AdminContactRequestDetail> {
|
|
return this.http.get<AdminContactRequestDetail>(
|
|
`${this.baseUrl}/contact-requests/${requestId}`,
|
|
{ withCredentials: true },
|
|
);
|
|
}
|
|
|
|
updateContactRequestStatus(
|
|
requestId: string,
|
|
payload: AdminUpdateContactRequestStatusPayload,
|
|
): Observable<AdminContactRequestDetail> {
|
|
return this.http.patch<AdminContactRequestDetail>(
|
|
`${this.baseUrl}/contact-requests/${requestId}/status`,
|
|
payload,
|
|
{ withCredentials: true },
|
|
);
|
|
}
|
|
|
|
downloadContactRequestAttachment(
|
|
requestId: string,
|
|
attachmentId: string,
|
|
): Observable<Blob> {
|
|
return this.http.get(
|
|
`${this.baseUrl}/contact-requests/${requestId}/attachments/${attachmentId}/file`,
|
|
{
|
|
withCredentials: true,
|
|
responseType: 'blob',
|
|
},
|
|
);
|
|
}
|
|
|
|
getSessions(): Observable<AdminQuoteSession[]> {
|
|
return this.http.get<AdminQuoteSession[]>(`${this.baseUrl}/sessions`, {
|
|
withCredentials: true,
|
|
});
|
|
}
|
|
|
|
deleteSession(sessionId: string): Observable<void> {
|
|
return this.http.delete<void>(`${this.baseUrl}/sessions/${sessionId}`, {
|
|
withCredentials: true,
|
|
});
|
|
}
|
|
|
|
getSessionDetail(sessionId: string): Observable<AdminQuoteSessionDetail> {
|
|
return this.http.get<AdminQuoteSessionDetail>(
|
|
`${environment.apiUrl}/api/quote-sessions/${sessionId}`,
|
|
{ withCredentials: true },
|
|
);
|
|
}
|
|
}
|