fix bugs phase 2 (excel ) , download sample feature

Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
2026-05-01 11:04:38 +03:00
co-authored by Copilot
parent e1ef6fa2ea
commit 97364f4734
24 changed files with 597 additions and 85 deletions
+52
View File
@@ -1700,6 +1700,19 @@
}
}
},
"/api/customers/import/sample": {
"get": {
"tags": [
"Customers"
],
"summary": "Download customers import sample (xlsx/csv)",
"responses": {
"200": {
"description": "OK"
}
}
}
},
"/api/customers/import": {
"post": {
"tags": [
@@ -5122,6 +5135,19 @@
}
}
},
"/api/vehicles/import/sample": {
"get": {
"tags": [
"Vehicles"
],
"summary": "Download vehicles import sample (xlsx/csv)",
"responses": {
"200": {
"description": "OK"
}
}
}
},
"/api/vehicles/import": {
"post": {
"tags": [
@@ -32921,6 +32947,19 @@
}
}
},
"/api/parts/import/sample": {
"get": {
"tags": [
"Import Parts"
],
"summary": "Download parts import sample (xlsx/csv)",
"responses": {
"200": {
"description": "OK"
}
}
}
},
"/api/parts/import": {
"post": {
"tags": [
@@ -35132,6 +35171,19 @@
}
}
},
"/api/services/import/sample": {
"get": {
"tags": [
"Import Services"
],
"summary": "Download services import sample (xlsx/csv)",
"responses": {
"200": {
"description": "OK"
}
}
}
},
"/api/import-services": {
"post": {
"tags": [
+176 -3
View File
@@ -1,6 +1,6 @@
{
"info": {
"_postman_id": "6ef9e473-ce87-4b4b-9e48-89d153d50fca",
"_postman_id": "559bc27f-b656-4554-a080-73c56d317ce5",
"name": "Reparee Collection",
"description": "Auto-generated from OpenAPI spec. Import storage/app/openapi-default.json for the full schema.",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
@@ -1343,6 +1343,48 @@
}
]
},
{
"name": "Download customers import sample (xlsx/csv)",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "{{auth_token}}",
"type": "string"
}
]
},
"method": "GET",
"header": [
{
"key": "Accept",
"value": "*/*"
}
],
"url": {
"raw": "{{base_url}}/api/customers/import/sample?format=xlsx",
"host": [
"{{base_url}}"
],
"path": [
"api",
"customers",
"import",
"sample"
],
"query": [
{
"key": "format",
"value": "xlsx",
"description": "xlsx | csv"
}
]
}
},
"response": []
},
{
"name": "Import customers from Excel file.",
"request": {
@@ -4917,6 +4959,48 @@
}
]
},
{
"name": "Download vehicles import sample (xlsx/csv)",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "{{auth_token}}",
"type": "string"
}
]
},
"method": "GET",
"header": [
{
"key": "Accept",
"value": "*/*"
}
],
"url": {
"raw": "{{base_url}}/api/vehicles/import/sample?format=xlsx",
"host": [
"{{base_url}}"
],
"path": [
"api",
"vehicles",
"import",
"sample"
],
"query": [
{
"key": "format",
"value": "xlsx",
"description": "xlsx | csv"
}
]
}
},
"response": []
},
{
"name": "Import vehicles from Excel file.",
"request": {
@@ -24371,6 +24455,48 @@
{
"name": "Import Parts",
"item": [
{
"name": "Download parts import sample (xlsx/csv)",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "{{auth_token}}",
"type": "string"
}
]
},
"method": "GET",
"header": [
{
"key": "Accept",
"value": "*/*"
}
],
"url": {
"raw": "{{base_url}}/api/parts/import/sample?format=xlsx",
"host": [
"{{base_url}}"
],
"path": [
"api",
"parts",
"import",
"sample"
],
"query": [
{
"key": "format",
"value": "xlsx",
"description": "xlsx | csv"
}
]
}
},
"response": []
},
{
"name": "Import parts from Excel file.",
"request": {
@@ -26187,6 +26313,48 @@
{
"name": "Import Services",
"item": [
{
"name": "Download services import sample (xlsx/csv)",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "{{auth_token}}",
"type": "string"
}
]
},
"method": "GET",
"header": [
{
"key": "Accept",
"value": "*/*"
}
],
"url": {
"raw": "{{base_url}}/api/services/import/sample?format=xlsx",
"host": [
"{{base_url}}"
],
"path": [
"api",
"services",
"import",
"sample"
],
"query": [
{
"key": "format",
"value": "xlsx",
"description": "xlsx | csv"
}
]
}
},
"response": []
},
{
"name": "Import services from Excel file.",
"request": {
@@ -43393,7 +43561,7 @@
{
"key": "type",
"value": "invoice",
"description": "inspection | estimate | job_card | invoice | payment_received | expense | purchase_order | bill | payment_made"
"description": "Allowed values: inspection | estimate | job_card | invoice | payment_received | expense | purchase_order | bill | payment_made"
},
{
"key": "id",
@@ -43435,7 +43603,12 @@
],
"body": {
"mode": "raw",
"raw": "{\n \"type\": \"job_card\",\n \"id\": 1,\n \"mode\": \"print\"\n}"
"raw": "{\n \"type\": \"job_card\",\n \"id\": 1,\n \"mode\": \"print\"\n}",
"options": {
"raw": {
"language": "json"
}
}
},
"url": {
"raw": "{{base_url}}/api/document-print",
+14 -9
View File
@@ -1,6 +1,6 @@
import { CrudClient } from "../infra/crud-client"
import { ApiClient, type ApiClientOptions } from "../infra/client"
import type { ApiPath, ApiRequestBody } from "../infra/types"
import type { ApiClientOptions } from "../infra/client"
import type { ApiPath } from "../infra/types"
import type { ApiListQueryParams } from "../contracts/types"
export const CUSTOMER_ROUTES = {
@@ -8,6 +8,7 @@ export const CUSTOMER_ROUTES = {
BY_ID: "/api/customers/{id}",
EXPORT: "/api/customers/export",
IMPORT: "/api/customers/import",
IMPORT_SAMPLE: "/api/customers/import/sample",
CUSTOMER_TYPES: "/api/customer-types",
NOTES: "/api/customers/{id}/notes/{note_id}",
} as const satisfies Record<string, ApiPath>
@@ -15,7 +16,15 @@ export const CUSTOMER_ROUTES = {
export class CustomersClient extends CrudClient<typeof CUSTOMER_ROUTES.INDEX, typeof CUSTOMER_ROUTES.BY_ID> {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions, CUSTOMER_ROUTES.INDEX, CUSTOMER_ROUTES.BY_ID)
super(
baseUrl,
defaultOptions,
CUSTOMER_ROUTES.INDEX,
CUSTOMER_ROUTES.BY_ID,
CUSTOMER_ROUTES.IMPORT,
CUSTOMER_ROUTES.EXPORT,
"GET",
)
}
async getById(id: string) {
@@ -26,12 +35,8 @@ export class CustomersClient extends CrudClient<typeof CUSTOMER_ROUTES.INDEX, ty
return this.get(CUSTOMER_ROUTES.CUSTOMER_TYPES, query ? { query } as never : undefined)
}
async export() {
return this.get(CUSTOMER_ROUTES.EXPORT)
}
async import(payload: ApiRequestBody<typeof CUSTOMER_ROUTES.IMPORT, "post">) {
return this.post(CUSTOMER_ROUTES.IMPORT, payload)
async downloadImportSample() {
return this.fetchBlob(CUSTOMER_ROUTES.IMPORT_SAMPLE, { method: "GET" })
}
async addNote(id: string, payload: { note: string }) {
+12 -7
View File
@@ -8,6 +8,7 @@ export const VEHICLE_ROUTES = {
BY_ID: "/api/vehicles/{id}",
EXPORT: "/api/vehicles/export",
IMPORT: "/api/vehicles/import",
IMPORT_SAMPLE: "/api/vehicles/import/sample",
GET_OWNERS: "/api/get-vehicle-owners",
LINK_CUSTOMER: "/api/link-customer-to-vehicle",
UNLINK_CUSTOMER: "/api/unlink-customer-from-vehicle",
@@ -31,7 +32,15 @@ export class VehiclesClient extends CrudClient<
typeof VEHICLE_ROUTES.BY_ID
> {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions, VEHICLE_ROUTES.INDEX, VEHICLE_ROUTES.BY_ID)
super(
baseUrl,
defaultOptions,
VEHICLE_ROUTES.INDEX,
VEHICLE_ROUTES.BY_ID,
VEHICLE_ROUTES.IMPORT,
VEHICLE_ROUTES.EXPORT,
"GET",
)
}
@@ -53,12 +62,8 @@ export class VehiclesClient extends CrudClient<
return this.postFormData(url, fd)
}
async export() {
return this.get(VEHICLE_ROUTES.EXPORT)
}
async import(payload: ApiRequestBody<typeof VEHICLE_ROUTES.IMPORT, "post">) {
return this.post(VEHICLE_ROUTES.IMPORT, payload)
async downloadImportSample() {
return this.fetchBlob(VEHICLE_ROUTES.IMPORT_SAMPLE, { method: "GET" })
}
async getOwners(vehicleId: string | number, query?: ApiListQueryParams) {
+1 -1
View File
@@ -72,7 +72,7 @@ export abstract class CrudClient<
if (this.exportMethod === "POST") {
return this.fetchBlob(route, { method: "POST", body: filters ?? {} })
}
return this.fetchBlob(route)
return this.fetchBlob(route, { method: "GET" })
}
}
+136
View File
@@ -1005,6 +1005,40 @@ export interface paths {
patch?: never;
trace?: never;
};
"/api/customers/import/sample": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/** Download customers import sample (xlsx/csv) */
get: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description OK */
200: {
headers: {
[name: string]: unknown;
};
content?: never;
};
};
};
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/customers/import": {
parameters: {
query?: never;
@@ -3568,6 +3602,40 @@ export interface paths {
patch?: never;
trace?: never;
};
"/api/vehicles/import/sample": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/** Download vehicles import sample (xlsx/csv) */
get: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description OK */
200: {
headers: {
[name: string]: unknown;
};
content?: never;
};
};
};
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/vehicles/import": {
parameters: {
query?: never;
@@ -22368,6 +22436,40 @@ export interface paths {
patch?: never;
trace?: never;
};
"/api/parts/import/sample": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/** Download parts import sample (xlsx/csv) */
get: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description OK */
200: {
headers: {
[name: string]: unknown;
};
content?: never;
};
};
};
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/parts/import": {
parameters: {
query?: never;
@@ -23938,6 +24040,40 @@ export interface paths {
patch?: never;
trace?: never;
};
"/api/services/import/sample": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/** Download services import sample (xlsx/csv) */
get: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description OK */
200: {
headers: {
[name: string]: unknown;
};
content?: never;
};
};
};
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/import-services": {
parameters: {
query?: never;