Skip to content

Commit de50d75

Browse files
committed
Add autocomplete, services and inventory UI
Introduce remote-search autocomplete and related backend models/services; enhance product form with inventory tab and invoiced flag. Key changes: - New models: categories, category options, manufacturers, manufacturer options, general query, product request payload. - Utility: buildHttpParams for HttpParams construction. - Services: CategoryService, ManufacturerService, StatusService (use environment.apiUrl). - Design system: AutocompleteSelect component (TS/HTML/CSS) and new icon cases (archive, receipt). - Product form: integrate autocomplete for category/manufacturer, async search with debounced Subjects, add "inventario" tab, inventory fields (warehouse, quantity, min/max, allow_backorder), is_invoiced flag, update payload to include inventory object. - Minor: update index.html title to "RECCOS Shop Car". These changes enable real-time option loading from the API and extend product creation with inventory management.
1 parent 838c93b commit de50d75

17 files changed

Lines changed: 914 additions & 59 deletions
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
export interface CategoryResponse {
2+
id: string;
3+
parent_id: null;
4+
name: string;
5+
slug: string;
6+
description: string;
7+
display_order: number;
8+
icon: string;
9+
image: string;
10+
active: boolean;
11+
created_at: string;
12+
updated_at: string;
13+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
export interface CategoryOptionsResponse {
2+
success: boolean;
3+
message: string;
4+
data: CategoryOption[];
5+
}
6+
7+
export interface CategoryOption {
8+
id: string;
9+
label: string;
10+
description: string;
11+
icon: string;
12+
}
13+
// 001400_ARARAS_PT1 => http://localhost:4200/#/my-farms/bagaco_03_30/72529
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
export interface GeneralOptionQuery {
2+
search: string | null;
3+
active: boolean | null;
4+
limit: number | null;
5+
}
6+
7+
// ALTERNATIVA PRA PAGINAÇÃO
8+
// {
9+
// page?: number;
10+
// limit?: number;
11+
// query?: string;
12+
// active?: boolean;
13+
// }
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export interface ManufacturerResponse {
2+
id: string;
3+
name: string;
4+
slug: string;
5+
website: string;
6+
active: boolean;
7+
image: null;
8+
created_at: string;
9+
updated_at: string;
10+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
export interface ManufacturerOptionsResponse {
2+
success: boolean;
3+
message: string;
4+
data: ManufacturerOption[];
5+
}
6+
7+
export interface ManufacturerOption {
8+
id: string;
9+
label: string;
10+
description: string;
11+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
export interface CreateProductPayload {
2+
category_id: string;
3+
manufacturer_id: string;
4+
status_id?: string;
5+
6+
internal_code: string;
7+
name: string;
8+
9+
slug?: string;
10+
icon?: string;
11+
image?: string;
12+
13+
short_description?: string;
14+
description?: string;
15+
16+
weight?: number;
17+
height?: number;
18+
width?: number;
19+
length?: number;
20+
21+
active?: boolean;
22+
featured?: boolean;
23+
24+
unit?: string;
25+
26+
price: ProductPricePayload;
27+
28+
inventory: ProductInventoryPayload;
29+
}
30+
31+
export interface ProductPricePayload {
32+
price: number;
33+
promotional_price?: number;
34+
promotion_start?: string; // YYYY-MM-DD
35+
promotion_end?: string; // YYYY-MM-DD
36+
}
37+
38+
export interface ProductInventoryPayload {
39+
warehouse_id: string;
40+
41+
quantity: number;
42+
43+
minimum_quantity?: number;
44+
maximum_quantity?: number;
45+
46+
allow_backorder?: boolean;
47+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { HttpParams } from '@angular/common/http';
2+
3+
export function buildHttpParams(params: Record<string, any>): HttpParams {
4+
let httpParams = new HttpParams();
5+
6+
Object.entries(params).forEach(([key, value]) => {
7+
if (value !== null && value !== undefined && value !== '') {
8+
httpParams = httpParams.set(key, String(value));
9+
}
10+
});
11+
12+
return httpParams;
13+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { HttpClient } from '@angular/common/http';
2+
import { inject, Injectable } from '@angular/core';
3+
import { PaginatedResponse } from '../models/pagination/pagination.model';
4+
import { environment } from '../../../environments/environment';
5+
import { CategoryResponse } from '../models/catetories/categories.model';
6+
import { buildHttpParams } from './build-http-params';
7+
import { CategoryOptionsResponse } from '../models/catetories/category-options.model';
8+
import { GeneralOptionQuery } from '../models/generals/general-option-query.model';
9+
10+
@Injectable({
11+
providedIn: 'root',
12+
})
13+
export class CategoryService {
14+
private http = inject(HttpClient);
15+
private api = environment.apiUrl;
16+
private flag = 'category';
17+
18+
getAll() {
19+
return this.http.get<PaginatedResponse<CategoryResponse>>(`${this.api}/${this.flag}`);
20+
}
21+
22+
getOptions(filters: GeneralOptionQuery) {
23+
const params = buildHttpParams(filters);
24+
return this.http.get<CategoryOptionsResponse>(`${this.api}/${this.flag}/options`, { params });
25+
}
26+
27+
getById(id: string) {
28+
return this.http.get<CategoryResponse>(`${this.api}/${this.flag}/${id}`);
29+
}
30+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { HttpClient } from '@angular/common/http';
2+
import { inject, Injectable } from '@angular/core';
3+
import { PaginatedResponse } from '../models/pagination/pagination.model';
4+
import { environment } from '../../../environments/environment';
5+
import { buildHttpParams } from './build-http-params';
6+
import { ManufacturerResponse } from '../models/manufactureres/manufacturer-response.model';
7+
import { GeneralOptionQuery } from '../models/generals/general-option-query.model';
8+
import { ManufacturerOptionsResponse } from '../models/manufactureres/manufaturer-options.model';
9+
10+
@Injectable({
11+
providedIn: 'root',
12+
})
13+
export class ManufacturerService {
14+
private http = inject(HttpClient);
15+
private api = environment.apiUrl;
16+
private flag = 'manufacturer';
17+
18+
getAll() {
19+
return this.http.get<PaginatedResponse<ManufacturerResponse>>(`${this.api}/${this.flag}`);
20+
}
21+
22+
getOptions(filters: GeneralOptionQuery) {
23+
const params = buildHttpParams(filters);
24+
return this.http.get<ManufacturerOptionsResponse>(`${this.api}/${this.flag}/options`, {
25+
params,
26+
});
27+
}
28+
29+
getById(id: string) {
30+
return this.http.get<ManufacturerResponse>(`${this.api}/${this.flag}/${id}`);
31+
}
32+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { HttpClient } from '@angular/common/http';
2+
import { inject, Injectable } from '@angular/core';
3+
import { PaginatedResponse } from '../models/pagination/pagination.model';
4+
import { ProductResponse } from '../models/products/product-response.model';
5+
import { environment } from '../../../environments/environment';
6+
7+
@Injectable({
8+
providedIn: 'root',
9+
})
10+
export class StatusService {
11+
private http = inject(HttpClient);
12+
private api = environment.apiUrl;
13+
private flag = 'status';
14+
15+
getAll() {
16+
return this.http.get<PaginatedResponse<ProductResponse>>(`${this.api}/${this.flag}`);
17+
}
18+
}

0 commit comments

Comments
 (0)