k
This commit is contained in:
@@ -37,6 +37,10 @@ export type { ClientUpdateRequest } from './models/ClientUpdateRequest';
|
|||||||
export type { ClientUpdateResponse } from './models/ClientUpdateResponse';
|
export type { ClientUpdateResponse } from './models/ClientUpdateResponse';
|
||||||
export type { CreateBarcodeTemplateAttributeRequest } from './models/CreateBarcodeTemplateAttributeRequest';
|
export type { CreateBarcodeTemplateAttributeRequest } from './models/CreateBarcodeTemplateAttributeRequest';
|
||||||
export type { CreateBarcodeTemplateAttributeResponse } from './models/CreateBarcodeTemplateAttributeResponse';
|
export type { CreateBarcodeTemplateAttributeResponse } from './models/CreateBarcodeTemplateAttributeResponse';
|
||||||
|
export type { CreatePaymentRecordRequest } from './models/CreatePaymentRecordRequest';
|
||||||
|
export type { CreatePaymentRecordResponse } from './models/CreatePaymentRecordResponse';
|
||||||
|
export type { CreatePayRateRequest } from './models/CreatePayRateRequest';
|
||||||
|
export type { CreatePayRateResponse } from './models/CreatePayRateResponse';
|
||||||
export type { CreatePositionRequest } from './models/CreatePositionRequest';
|
export type { CreatePositionRequest } from './models/CreatePositionRequest';
|
||||||
export type { CreatePositionResponse } from './models/CreatePositionResponse';
|
export type { CreatePositionResponse } from './models/CreatePositionResponse';
|
||||||
export type { DealAddProductRequest } from './models/DealAddProductRequest';
|
export type { DealAddProductRequest } from './models/DealAddProductRequest';
|
||||||
@@ -80,24 +84,36 @@ export type { DealUpdateServiceQuantityRequest } from './models/DealUpdateServic
|
|||||||
export type { DealUpdateServiceQuantityResponse } from './models/DealUpdateServiceQuantityResponse';
|
export type { DealUpdateServiceQuantityResponse } from './models/DealUpdateServiceQuantityResponse';
|
||||||
export type { DealUpdateServiceRequest } from './models/DealUpdateServiceRequest';
|
export type { DealUpdateServiceRequest } from './models/DealUpdateServiceRequest';
|
||||||
export type { DealUpdateServiceResponse } from './models/DealUpdateServiceResponse';
|
export type { DealUpdateServiceResponse } from './models/DealUpdateServiceResponse';
|
||||||
|
export type { DeletePaymentRecordRequest } from './models/DeletePaymentRecordRequest';
|
||||||
|
export type { DeletePaymentRecordResponse } from './models/DeletePaymentRecordResponse';
|
||||||
|
export type { DeletePayRateRequest } from './models/DeletePayRateRequest';
|
||||||
|
export type { DeletePayRateResponse } from './models/DeletePayRateResponse';
|
||||||
export type { DeletePositionRequest } from './models/DeletePositionRequest';
|
export type { DeletePositionRequest } from './models/DeletePositionRequest';
|
||||||
export type { DeletePositionResponse } from './models/DeletePositionResponse';
|
export type { DeletePositionResponse } from './models/DeletePositionResponse';
|
||||||
export type { GetAllBarcodeTemplateAttributesResponse } from './models/GetAllBarcodeTemplateAttributesResponse';
|
export type { GetAllBarcodeTemplateAttributesResponse } from './models/GetAllBarcodeTemplateAttributesResponse';
|
||||||
export type { GetAllBarcodeTemplateSizesResponse } from './models/GetAllBarcodeTemplateSizesResponse';
|
export type { GetAllBarcodeTemplateSizesResponse } from './models/GetAllBarcodeTemplateSizesResponse';
|
||||||
export type { GetAllBarcodeTemplatesResponse } from './models/GetAllBarcodeTemplatesResponse';
|
export type { GetAllBarcodeTemplatesResponse } from './models/GetAllBarcodeTemplatesResponse';
|
||||||
export type { GetAllBaseMarketplacesResponse } from './models/GetAllBaseMarketplacesResponse';
|
export type { GetAllBaseMarketplacesResponse } from './models/GetAllBaseMarketplacesResponse';
|
||||||
|
export type { GetAllPayRatesResponse } from './models/GetAllPayRatesResponse';
|
||||||
|
export type { GetAllPayrollSchemeResponse } from './models/GetAllPayrollSchemeResponse';
|
||||||
export type { GetAllPositionsResponse } from './models/GetAllPositionsResponse';
|
export type { GetAllPositionsResponse } from './models/GetAllPositionsResponse';
|
||||||
export type { GetAllRolesResponse } from './models/GetAllRolesResponse';
|
export type { GetAllRolesResponse } from './models/GetAllRolesResponse';
|
||||||
export type { GetAllShippingWarehousesResponse } from './models/GetAllShippingWarehousesResponse';
|
export type { GetAllShippingWarehousesResponse } from './models/GetAllShippingWarehousesResponse';
|
||||||
export type { GetAllUsersResponse } from './models/GetAllUsersResponse';
|
export type { GetAllUsersResponse } from './models/GetAllUsersResponse';
|
||||||
export type { GetBarcodeTemplateByIdRequest } from './models/GetBarcodeTemplateByIdRequest';
|
export type { GetBarcodeTemplateByIdRequest } from './models/GetBarcodeTemplateByIdRequest';
|
||||||
export type { GetBarcodeTemplateByIdResponse } from './models/GetBarcodeTemplateByIdResponse';
|
export type { GetBarcodeTemplateByIdResponse } from './models/GetBarcodeTemplateByIdResponse';
|
||||||
|
export type { GetPaymentRecordsResponse } from './models/GetPaymentRecordsResponse';
|
||||||
export type { GetProductBarcodePdfRequest } from './models/GetProductBarcodePdfRequest';
|
export type { GetProductBarcodePdfRequest } from './models/GetProductBarcodePdfRequest';
|
||||||
export type { GetProductBarcodePdfResponse } from './models/GetProductBarcodePdfResponse';
|
export type { GetProductBarcodePdfResponse } from './models/GetProductBarcodePdfResponse';
|
||||||
export type { GetProductBarcodeRequest } from './models/GetProductBarcodeRequest';
|
export type { GetProductBarcodeRequest } from './models/GetProductBarcodeRequest';
|
||||||
export type { GetProductBarcodeResponse } from './models/GetProductBarcodeResponse';
|
export type { GetProductBarcodeResponse } from './models/GetProductBarcodeResponse';
|
||||||
export type { HTTPValidationError } from './models/HTTPValidationError';
|
export type { HTTPValidationError } from './models/HTTPValidationError';
|
||||||
export type { PaginationInfoSchema } from './models/PaginationInfoSchema';
|
export type { PaginationInfoSchema } from './models/PaginationInfoSchema';
|
||||||
|
export type { PaymentRecordCreateSchema } from './models/PaymentRecordCreateSchema';
|
||||||
|
export type { PaymentRecordGetSchema } from './models/PaymentRecordGetSchema';
|
||||||
|
export type { PayRateSchema } from './models/PayRateSchema';
|
||||||
|
export type { PayRateSchemaBase } from './models/PayRateSchemaBase';
|
||||||
|
export type { PayrollSchemeSchema } from './models/PayrollSchemeSchema';
|
||||||
export type { PermissionSchema } from './models/PermissionSchema';
|
export type { PermissionSchema } from './models/PermissionSchema';
|
||||||
export type { PositionSchema } from './models/PositionSchema';
|
export type { PositionSchema } from './models/PositionSchema';
|
||||||
export type { ProductAddBarcodeRequest } from './models/ProductAddBarcodeRequest';
|
export type { ProductAddBarcodeRequest } from './models/ProductAddBarcodeRequest';
|
||||||
@@ -130,6 +146,8 @@ export type { ServiceSchema } from './models/ServiceSchema';
|
|||||||
export type { ServiceUpdateRequest } from './models/ServiceUpdateRequest';
|
export type { ServiceUpdateRequest } from './models/ServiceUpdateRequest';
|
||||||
export type { ServiceUpdateResponse } from './models/ServiceUpdateResponse';
|
export type { ServiceUpdateResponse } from './models/ServiceUpdateResponse';
|
||||||
export type { ShippingWarehouseSchema } from './models/ShippingWarehouseSchema';
|
export type { ShippingWarehouseSchema } from './models/ShippingWarehouseSchema';
|
||||||
|
export type { UpdatePayRateRequest } from './models/UpdatePayRateRequest';
|
||||||
|
export type { UpdatePayRateResponse } from './models/UpdatePayRateResponse';
|
||||||
export type { UpdateUserRequest } from './models/UpdateUserRequest';
|
export type { UpdateUserRequest } from './models/UpdateUserRequest';
|
||||||
export type { UpdateUserResponse } from './models/UpdateUserResponse';
|
export type { UpdateUserResponse } from './models/UpdateUserResponse';
|
||||||
export type { UserSchema } from './models/UserSchema';
|
export type { UserSchema } from './models/UserSchema';
|
||||||
@@ -141,6 +159,7 @@ export { BarcodeService } from './services/BarcodeService';
|
|||||||
export { ClientService } from './services/ClientService';
|
export { ClientService } from './services/ClientService';
|
||||||
export { DealService } from './services/DealService';
|
export { DealService } from './services/DealService';
|
||||||
export { MarketplaceService } from './services/MarketplaceService';
|
export { MarketplaceService } from './services/MarketplaceService';
|
||||||
|
export { PayrollService } from './services/PayrollService';
|
||||||
export { PositionService } from './services/PositionService';
|
export { PositionService } from './services/PositionService';
|
||||||
export { ProductService } from './services/ProductService';
|
export { ProductService } from './services/ProductService';
|
||||||
export { RoleService } from './services/RoleService';
|
export { RoleService } from './services/RoleService';
|
||||||
|
|||||||
9
src/client/models/CreatePayRateRequest.ts
Normal file
9
src/client/models/CreatePayRateRequest.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
import type { PayRateSchemaBase } from './PayRateSchemaBase';
|
||||||
|
export type CreatePayRateRequest = {
|
||||||
|
data: PayRateSchemaBase;
|
||||||
|
};
|
||||||
|
|
||||||
9
src/client/models/CreatePayRateResponse.ts
Normal file
9
src/client/models/CreatePayRateResponse.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
export type CreatePayRateResponse = {
|
||||||
|
ok: boolean;
|
||||||
|
message: string;
|
||||||
|
};
|
||||||
|
|
||||||
9
src/client/models/CreatePaymentRecordRequest.ts
Normal file
9
src/client/models/CreatePaymentRecordRequest.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
import type { PaymentRecordCreateSchema } from './PaymentRecordCreateSchema';
|
||||||
|
export type CreatePaymentRecordRequest = {
|
||||||
|
data: PaymentRecordCreateSchema;
|
||||||
|
};
|
||||||
|
|
||||||
9
src/client/models/CreatePaymentRecordResponse.ts
Normal file
9
src/client/models/CreatePaymentRecordResponse.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
export type CreatePaymentRecordResponse = {
|
||||||
|
ok: boolean;
|
||||||
|
message: string;
|
||||||
|
};
|
||||||
|
|
||||||
8
src/client/models/DeletePayRateRequest.ts
Normal file
8
src/client/models/DeletePayRateRequest.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
export type DeletePayRateRequest = {
|
||||||
|
payRateId: number;
|
||||||
|
};
|
||||||
|
|
||||||
9
src/client/models/DeletePayRateResponse.ts
Normal file
9
src/client/models/DeletePayRateResponse.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
export type DeletePayRateResponse = {
|
||||||
|
ok: boolean;
|
||||||
|
message: string;
|
||||||
|
};
|
||||||
|
|
||||||
8
src/client/models/DeletePaymentRecordRequest.ts
Normal file
8
src/client/models/DeletePaymentRecordRequest.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
export type DeletePaymentRecordRequest = {
|
||||||
|
paymentRecordId: number;
|
||||||
|
};
|
||||||
|
|
||||||
9
src/client/models/DeletePaymentRecordResponse.ts
Normal file
9
src/client/models/DeletePaymentRecordResponse.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
export type DeletePaymentRecordResponse = {
|
||||||
|
ok: boolean;
|
||||||
|
message: string;
|
||||||
|
};
|
||||||
|
|
||||||
9
src/client/models/GetAllPayRatesResponse.ts
Normal file
9
src/client/models/GetAllPayRatesResponse.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
import type { PayRateSchema } from './PayRateSchema';
|
||||||
|
export type GetAllPayRatesResponse = {
|
||||||
|
payRates: Array<PayRateSchema>;
|
||||||
|
};
|
||||||
|
|
||||||
9
src/client/models/GetAllPayrollSchemeResponse.ts
Normal file
9
src/client/models/GetAllPayrollSchemeResponse.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
import type { PayrollSchemeSchema } from './PayrollSchemeSchema';
|
||||||
|
export type GetAllPayrollSchemeResponse = {
|
||||||
|
payrollSchemas: Array<PayrollSchemeSchema>;
|
||||||
|
};
|
||||||
|
|
||||||
11
src/client/models/GetPaymentRecordsResponse.ts
Normal file
11
src/client/models/GetPaymentRecordsResponse.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
import type { PaginationInfoSchema } from './PaginationInfoSchema';
|
||||||
|
import type { PaymentRecordGetSchema } from './PaymentRecordGetSchema';
|
||||||
|
export type GetPaymentRecordsResponse = {
|
||||||
|
paymentRecords: Array<PaymentRecordGetSchema>;
|
||||||
|
paginationInfo: PaginationInfoSchema;
|
||||||
|
};
|
||||||
|
|
||||||
14
src/client/models/PayRateSchema.ts
Normal file
14
src/client/models/PayRateSchema.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
import type { PayrollSchemeSchema } from './PayrollSchemeSchema';
|
||||||
|
export type PayRateSchema = {
|
||||||
|
name: string;
|
||||||
|
payrollScheme: PayrollSchemeSchema;
|
||||||
|
baseRate: number;
|
||||||
|
overtimeRate?: (number | null);
|
||||||
|
overtimeThreshold?: (number | null);
|
||||||
|
id: number;
|
||||||
|
};
|
||||||
|
|
||||||
13
src/client/models/PayRateSchemaBase.ts
Normal file
13
src/client/models/PayRateSchemaBase.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
import type { PayrollSchemeSchema } from './PayrollSchemeSchema';
|
||||||
|
export type PayRateSchemaBase = {
|
||||||
|
name: string;
|
||||||
|
payrollScheme: PayrollSchemeSchema;
|
||||||
|
baseRate: number;
|
||||||
|
overtimeRate?: (number | null);
|
||||||
|
overtimeThreshold?: (number | null);
|
||||||
|
};
|
||||||
|
|
||||||
12
src/client/models/PaymentRecordCreateSchema.ts
Normal file
12
src/client/models/PaymentRecordCreateSchema.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
import type { UserSchema } from './UserSchema';
|
||||||
|
export type PaymentRecordCreateSchema = {
|
||||||
|
startDate: string;
|
||||||
|
endDate: string;
|
||||||
|
workUnits: number;
|
||||||
|
user: UserSchema;
|
||||||
|
};
|
||||||
|
|
||||||
18
src/client/models/PaymentRecordGetSchema.ts
Normal file
18
src/client/models/PaymentRecordGetSchema.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
import type { PayrollSchemeSchema } from './PayrollSchemeSchema';
|
||||||
|
import type { UserSchema } from './UserSchema';
|
||||||
|
export type PaymentRecordGetSchema = {
|
||||||
|
startDate: string;
|
||||||
|
endDate: string;
|
||||||
|
workUnits: number;
|
||||||
|
user: UserSchema;
|
||||||
|
id: number;
|
||||||
|
createdByUser: UserSchema;
|
||||||
|
payrollScheme: PayrollSchemeSchema;
|
||||||
|
amount: number;
|
||||||
|
createdAt: string;
|
||||||
|
};
|
||||||
|
|
||||||
9
src/client/models/PayrollSchemeSchema.ts
Normal file
9
src/client/models/PayrollSchemeSchema.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
export type PayrollSchemeSchema = {
|
||||||
|
key: string;
|
||||||
|
name: string;
|
||||||
|
};
|
||||||
|
|
||||||
9
src/client/models/UpdatePayRateRequest.ts
Normal file
9
src/client/models/UpdatePayRateRequest.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
import type { PayRateSchema } from './PayRateSchema';
|
||||||
|
export type UpdatePayRateRequest = {
|
||||||
|
data: PayRateSchema;
|
||||||
|
};
|
||||||
|
|
||||||
9
src/client/models/UpdatePayRateResponse.ts
Normal file
9
src/client/models/UpdatePayRateResponse.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
export type UpdatePayRateResponse = {
|
||||||
|
ok: boolean;
|
||||||
|
message: string;
|
||||||
|
};
|
||||||
|
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
/* istanbul ignore file */
|
/* istanbul ignore file */
|
||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
|
import type { PayRateSchema } from './PayRateSchema';
|
||||||
import type { PositionSchema } from './PositionSchema';
|
import type { PositionSchema } from './PositionSchema';
|
||||||
import type { RoleSchema } from './RoleSchema';
|
import type { RoleSchema } from './RoleSchema';
|
||||||
export type UserSchema = {
|
export type UserSchema = {
|
||||||
@@ -15,6 +16,7 @@ export type UserSchema = {
|
|||||||
isBlocked: boolean;
|
isBlocked: boolean;
|
||||||
isDeleted: boolean;
|
isDeleted: boolean;
|
||||||
roleKey: string;
|
roleKey: string;
|
||||||
|
payRate?: (PayRateSchema | null);
|
||||||
role: RoleSchema;
|
role: RoleSchema;
|
||||||
position?: (PositionSchema | null);
|
position?: (PositionSchema | null);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
/* istanbul ignore file */
|
/* istanbul ignore file */
|
||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
|
import type { PayRateSchema } from './PayRateSchema';
|
||||||
export type UserUpdate = {
|
export type UserUpdate = {
|
||||||
id: number;
|
id: number;
|
||||||
telegramId: number;
|
telegramId: number;
|
||||||
@@ -13,6 +14,7 @@ export type UserUpdate = {
|
|||||||
isBlocked: boolean;
|
isBlocked: boolean;
|
||||||
isDeleted: boolean;
|
isDeleted: boolean;
|
||||||
roleKey: string;
|
roleKey: string;
|
||||||
|
payRate?: (PayRateSchema | null);
|
||||||
positionKey?: (string | null);
|
positionKey?: (string | null);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
168
src/client/services/PayrollService.ts
Normal file
168
src/client/services/PayrollService.ts
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
import type { CreatePaymentRecordRequest } from '../models/CreatePaymentRecordRequest';
|
||||||
|
import type { CreatePaymentRecordResponse } from '../models/CreatePaymentRecordResponse';
|
||||||
|
import type { CreatePayRateRequest } from '../models/CreatePayRateRequest';
|
||||||
|
import type { CreatePayRateResponse } from '../models/CreatePayRateResponse';
|
||||||
|
import type { DeletePaymentRecordRequest } from '../models/DeletePaymentRecordRequest';
|
||||||
|
import type { DeletePaymentRecordResponse } from '../models/DeletePaymentRecordResponse';
|
||||||
|
import type { DeletePayRateRequest } from '../models/DeletePayRateRequest';
|
||||||
|
import type { DeletePayRateResponse } from '../models/DeletePayRateResponse';
|
||||||
|
import type { GetAllPayRatesResponse } from '../models/GetAllPayRatesResponse';
|
||||||
|
import type { GetAllPayrollSchemeResponse } from '../models/GetAllPayrollSchemeResponse';
|
||||||
|
import type { GetPaymentRecordsResponse } from '../models/GetPaymentRecordsResponse';
|
||||||
|
import type { UpdatePayRateRequest } from '../models/UpdatePayRateRequest';
|
||||||
|
import type { UpdatePayRateResponse } from '../models/UpdatePayRateResponse';
|
||||||
|
import type { CancelablePromise } from '../core/CancelablePromise';
|
||||||
|
import { OpenAPI } from '../core/OpenAPI';
|
||||||
|
import { request as __request } from '../core/request';
|
||||||
|
export class PayrollService {
|
||||||
|
/**
|
||||||
|
* Get All Schemas
|
||||||
|
* @returns GetAllPayrollSchemeResponse Successful Response
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
public static getAllPayrollSchemas(): CancelablePromise<GetAllPayrollSchemeResponse> {
|
||||||
|
return __request(OpenAPI, {
|
||||||
|
method: 'GET',
|
||||||
|
url: '/payroll/scheme/get-all',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Get All Pay Rates
|
||||||
|
* @returns GetAllPayRatesResponse Successful Response
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
public static getAllPayRates(): CancelablePromise<GetAllPayRatesResponse> {
|
||||||
|
return __request(OpenAPI, {
|
||||||
|
method: 'GET',
|
||||||
|
url: '/payroll/pay-rate/get-all',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Create Pay Rate
|
||||||
|
* @returns CreatePayRateResponse Successful Response
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
public static createPayRate({
|
||||||
|
requestBody,
|
||||||
|
}: {
|
||||||
|
requestBody: CreatePayRateRequest,
|
||||||
|
}): CancelablePromise<CreatePayRateResponse> {
|
||||||
|
return __request(OpenAPI, {
|
||||||
|
method: 'POST',
|
||||||
|
url: '/payroll/pay-rate/create',
|
||||||
|
body: requestBody,
|
||||||
|
mediaType: 'application/json',
|
||||||
|
errors: {
|
||||||
|
422: `Validation Error`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Update Pay Rate
|
||||||
|
* @returns UpdatePayRateResponse Successful Response
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
public static updatePayRate({
|
||||||
|
requestBody,
|
||||||
|
}: {
|
||||||
|
requestBody: UpdatePayRateRequest,
|
||||||
|
}): CancelablePromise<UpdatePayRateResponse> {
|
||||||
|
return __request(OpenAPI, {
|
||||||
|
method: 'POST',
|
||||||
|
url: '/payroll/pay-rate/update',
|
||||||
|
body: requestBody,
|
||||||
|
mediaType: 'application/json',
|
||||||
|
errors: {
|
||||||
|
422: `Validation Error`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Update Pay Rate
|
||||||
|
* @returns DeletePayRateResponse Successful Response
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
public static deletePayRate({
|
||||||
|
requestBody,
|
||||||
|
}: {
|
||||||
|
requestBody: DeletePayRateRequest,
|
||||||
|
}): CancelablePromise<DeletePayRateResponse> {
|
||||||
|
return __request(OpenAPI, {
|
||||||
|
method: 'POST',
|
||||||
|
url: '/payroll/pay-rate/delete',
|
||||||
|
body: requestBody,
|
||||||
|
mediaType: 'application/json',
|
||||||
|
errors: {
|
||||||
|
422: `Validation Error`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Get Payment Records
|
||||||
|
* @returns GetPaymentRecordsResponse Successful Response
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
public static getPaymentRecords({
|
||||||
|
page,
|
||||||
|
itemsPerPage,
|
||||||
|
}: {
|
||||||
|
page?: (number | null),
|
||||||
|
itemsPerPage?: (number | null),
|
||||||
|
}): CancelablePromise<GetPaymentRecordsResponse> {
|
||||||
|
return __request(OpenAPI, {
|
||||||
|
method: 'GET',
|
||||||
|
url: '/payroll/payment-record/get',
|
||||||
|
query: {
|
||||||
|
'page': page,
|
||||||
|
'items_per_page': itemsPerPage,
|
||||||
|
},
|
||||||
|
errors: {
|
||||||
|
422: `Validation Error`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Create Payment Records
|
||||||
|
* @returns CreatePaymentRecordResponse Successful Response
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
public static createPaymentRecord({
|
||||||
|
requestBody,
|
||||||
|
}: {
|
||||||
|
requestBody: CreatePaymentRecordRequest,
|
||||||
|
}): CancelablePromise<CreatePaymentRecordResponse> {
|
||||||
|
return __request(OpenAPI, {
|
||||||
|
method: 'POST',
|
||||||
|
url: '/payroll/payment-record/create',
|
||||||
|
body: requestBody,
|
||||||
|
mediaType: 'application/json',
|
||||||
|
errors: {
|
||||||
|
422: `Validation Error`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Delete Payment Record
|
||||||
|
* @returns DeletePaymentRecordResponse Successful Response
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
public static deletePaymentRecord({
|
||||||
|
requestBody,
|
||||||
|
}: {
|
||||||
|
requestBody: DeletePaymentRecordRequest,
|
||||||
|
}): CancelablePromise<DeletePaymentRecordResponse> {
|
||||||
|
return __request(OpenAPI, {
|
||||||
|
method: 'POST',
|
||||||
|
url: '/payroll/payment-record/delete',
|
||||||
|
body: requestBody,
|
||||||
|
mediaType: 'application/json',
|
||||||
|
errors: {
|
||||||
|
422: `Validation Error`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
|
||||||
@mixin light {
|
@mixin light {
|
||||||
background-color: var(--mantine-color-gray-0);
|
background-color: var(--mantine-color-gray-1);
|
||||||
}
|
}
|
||||||
@mixin dark {
|
@mixin dark {
|
||||||
background-color: var(--mantine-color-dark-5);
|
background-color: var(--mantine-color-dark-5);
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ const BaseMarketplaceSelect: FC<Props> = (props) => {
|
|||||||
<ObjectSelect
|
<ObjectSelect
|
||||||
renderOption={(baseMarketplace) =>
|
renderOption={(baseMarketplace) =>
|
||||||
<>
|
<>
|
||||||
<ActionIcon variant={"transparent"}>
|
<ActionIcon radius={"md"} variant={"transparent"}>
|
||||||
<Image
|
<Image
|
||||||
src={baseMarketplaces.find(el => baseMarketplace.option.value === el.key)?.iconUrl || ""}/>
|
src={baseMarketplaces.find(el => baseMarketplace.option.value === el.key)?.iconUrl || ""}/>
|
||||||
</ActionIcon>
|
</ActionIcon>
|
||||||
|
|||||||
19
src/components/Selects/PayRateSelect/PayRateSelect.tsx
Normal file
19
src/components/Selects/PayRateSelect/PayRateSelect.tsx
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import ObjectSelect, {ObjectSelectProps} from "../../ObjectSelect/ObjectSelect.tsx";
|
||||||
|
import {PayRateSchema} from "../../../client";
|
||||||
|
import {FC} from "react";
|
||||||
|
import usePayRatesList from "../../../pages/AdminPage/hooks/usePayRatesList.tsx";
|
||||||
|
|
||||||
|
type Props = Omit<ObjectSelectProps<PayRateSchema>, 'data' | 'getValueFn' | 'getLabelFn'>
|
||||||
|
|
||||||
|
const PayRateSelect: FC<Props> = (props) => {
|
||||||
|
const {objects: payRates} = usePayRatesList();
|
||||||
|
return (
|
||||||
|
<ObjectSelect
|
||||||
|
getValueFn={(baseMarketplace) => baseMarketplace.id.toLocaleString()}
|
||||||
|
getLabelFn={(baseMarketplace) => baseMarketplace.name}
|
||||||
|
data={payRates}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default PayRateSelect;
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import ObjectSelect, {ObjectSelectProps} from "../../ObjectSelect/ObjectSelect.tsx";
|
||||||
|
import {PayrollSchemeSchema} from "../../../client";
|
||||||
|
import {FC} from "react";
|
||||||
|
import usePayrollSchemasList from "../../../hooks/usePayrollSchemasList.tsx";
|
||||||
|
|
||||||
|
type Props = Omit<ObjectSelectProps<PayrollSchemeSchema>, 'data' | 'getValueFn' | 'getLabelFn'>
|
||||||
|
|
||||||
|
const PayrollSchemeSelect: FC<Props> = (props) => {
|
||||||
|
const {objects: payrollSchemeSchemas} = usePayrollSchemasList();
|
||||||
|
return (
|
||||||
|
<ObjectSelect
|
||||||
|
getValueFn={(baseMarketplace) => baseMarketplace.key}
|
||||||
|
getLabelFn={(baseMarketplace) => baseMarketplace.name}
|
||||||
|
data={payrollSchemeSchemas}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default PayrollSchemeSelect
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import {QueryObserverResult, RefetchOptions, useQuery} from "@tanstack/react-query";
|
import {QueryObserverResult, RefetchOptions, useQuery} from "@tanstack/react-query";
|
||||||
import {CancelablePromise} from "../client";
|
import {CancelablePromise, PaginationInfoSchema} from "../client";
|
||||||
|
import {Pagination} from "../types/Pagination.ts";
|
||||||
|
|
||||||
type Props<T, K> = {
|
type Props<T, K> = {
|
||||||
queryFn: () => CancelablePromise<T>,
|
queryFn: () => CancelablePromise<T>,
|
||||||
@@ -18,4 +19,33 @@ const ObjectList = <T, K, >(props: Props<T, K>): Response<T, K> => {
|
|||||||
const objects = isPending || error || !data ? ([] as K[]) : props.getObjectsFn(data);
|
const objects = isPending || error || !data ? ([] as K[]) : props.getObjectsFn(data);
|
||||||
return {objects, refetch}
|
return {objects, refetch}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ObjectWithPagination {
|
||||||
|
paginationInfo: PaginationInfoSchema
|
||||||
|
}
|
||||||
|
|
||||||
|
type PropsWithPagination<T extends ObjectWithPagination, K> = {
|
||||||
|
queryFn: () => CancelablePromise<T>,
|
||||||
|
getObjectsFn: (response: T) => K[],
|
||||||
|
queryKey: string,
|
||||||
|
pagination: Pagination
|
||||||
|
}
|
||||||
|
type ResponseWithPagination<T extends ObjectWithPagination, K> = {
|
||||||
|
objects: K[],
|
||||||
|
pagination?: PaginationInfoSchema,
|
||||||
|
refetch: (options?: RefetchOptions) => Promise<QueryObserverResult<T, Error>>
|
||||||
|
}
|
||||||
|
export const ObjectListWithPagination = <T extends ObjectWithPagination, K, >(props: PropsWithPagination<T, K>): ResponseWithPagination<T, K> => {
|
||||||
|
const {isPending, error, data, refetch} = useQuery({
|
||||||
|
queryKey: [props.queryKey, props, props.pagination.itemsPerPage, props.pagination.page],
|
||||||
|
queryFn: props.queryFn,
|
||||||
|
});
|
||||||
|
const objects = isPending || error || !data ? ([] as K[]) : props.getObjectsFn(data);
|
||||||
|
return {
|
||||||
|
objects,
|
||||||
|
pagination: data?.paginationInfo,
|
||||||
|
refetch
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default ObjectList
|
export default ObjectList
|
||||||
11
src/hooks/usePaymentRecordsList.tsx
Normal file
11
src/hooks/usePaymentRecordsList.tsx
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import {ObjectListWithPagination} from "./objectList.tsx";
|
||||||
|
import {PayrollService} from "../client";
|
||||||
|
import {Pagination} from "../types/Pagination.ts";
|
||||||
|
|
||||||
|
|
||||||
|
export const usePaymentRecordsList = (pagination: Pagination) => ObjectListWithPagination({
|
||||||
|
queryFn: () => PayrollService.getPaymentRecords(pagination),
|
||||||
|
queryKey: "getPaymentRecords",
|
||||||
|
getObjectsFn: (response) => response.paymentRecords,
|
||||||
|
pagination
|
||||||
|
})
|
||||||
9
src/hooks/usePayrollSchemasList.tsx
Normal file
9
src/hooks/usePayrollSchemasList.tsx
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import ObjectList from "./objectList.tsx";
|
||||||
|
import {PayrollService} from "../client";
|
||||||
|
|
||||||
|
const usePayrollSchemasList = () => ObjectList({
|
||||||
|
queryFn: PayrollService.getAllPayrollSchemas,
|
||||||
|
getObjectsFn: (response) => response.payrollSchemas,
|
||||||
|
queryKey: "getAllPayrollSchemas"
|
||||||
|
})
|
||||||
|
export default usePayrollSchemasList;
|
||||||
@@ -14,6 +14,8 @@ import UserFormModal from "../pages/AdminPage/modals/UserFormModal/UserFormModal
|
|||||||
import EmployeeSelectModal from "./EmployeeSelectModal/EmployeeSelectModal.tsx";
|
import EmployeeSelectModal from "./EmployeeSelectModal/EmployeeSelectModal.tsx";
|
||||||
import EmployeeTableModal from "./EmployeeTableModal/EmployeeTableModal.tsx";
|
import EmployeeTableModal from "./EmployeeTableModal/EmployeeTableModal.tsx";
|
||||||
import PositionFormModal from "./PositionFormModal/PositionFormModal.tsx";
|
import PositionFormModal from "./PositionFormModal/PositionFormModal.tsx";
|
||||||
|
import PayRateFormModal from "../pages/AdminPage/modals/PayRateFormModal/PayRateFormModal.tsx";
|
||||||
|
import CreatePaymentRecordModal from "../pages/AdminPage/modals/CreatePaymentRecordModal/CreatePaymentRecordModal.tsx";
|
||||||
|
|
||||||
export const modals = {
|
export const modals = {
|
||||||
enterDeadline: EnterDeadlineModal,
|
enterDeadline: EnterDeadlineModal,
|
||||||
@@ -30,5 +32,7 @@ export const modals = {
|
|||||||
userFormModal: UserFormModal,
|
userFormModal: UserFormModal,
|
||||||
employeeSelect: EmployeeSelectModal,
|
employeeSelect: EmployeeSelectModal,
|
||||||
employeeTable: EmployeeTableModal,
|
employeeTable: EmployeeTableModal,
|
||||||
positionForm: PositionFormModal
|
positionForm: PositionFormModal,
|
||||||
|
payRateForm: PayRateFormModal,
|
||||||
|
createPaymentRecord: CreatePaymentRecordModal
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import styles from './AdminPage.module.css';
|
import styles from './AdminPage.module.css';
|
||||||
import {Tabs} from "@mantine/core";
|
import {Tabs} from "@mantine/core";
|
||||||
import PageBlock from "../../components/PageBlock/PageBlock.tsx";
|
import PageBlock from "../../components/PageBlock/PageBlock.tsx";
|
||||||
import {IconBriefcase, IconUser} from "@tabler/icons-react";
|
import {IconBriefcase, IconCurrencyDollar, IconUser} from "@tabler/icons-react";
|
||||||
import RolesAndPositionsTab from "./tabs/RolesAndPositions/RolesAndPositionsTab.tsx";
|
import RolesAndPositionsTab from "./tabs/RolesAndPositions/RolesAndPositionsTab.tsx";
|
||||||
import UsersTab from "./tabs/Users/UsersTab.tsx";
|
import UsersTab from "./tabs/Users/UsersTab.tsx";
|
||||||
import {motion} from "framer-motion";
|
import {motion} from "framer-motion";
|
||||||
|
import FinancesTab from "./tabs/Finances/FinancesTab.tsx";
|
||||||
|
|
||||||
const AdminPage = () => {
|
const AdminPage = () => {
|
||||||
|
|
||||||
@@ -16,13 +17,15 @@ const AdminPage = () => {
|
|||||||
<Tabs.Tab value={"users"} leftSection={<IconUser/>}>
|
<Tabs.Tab value={"users"} leftSection={<IconUser/>}>
|
||||||
Пользователи
|
Пользователи
|
||||||
</Tabs.Tab>
|
</Tabs.Tab>
|
||||||
|
<Tabs.Tab value={"finances"} leftSection={<IconCurrencyDollar/>}>
|
||||||
|
Финансы
|
||||||
|
</Tabs.Tab>
|
||||||
<Tabs.Tab value={"rolesAndPositions"} leftSection={<IconBriefcase/>}>
|
<Tabs.Tab value={"rolesAndPositions"} leftSection={<IconBriefcase/>}>
|
||||||
Должности
|
Должности
|
||||||
</Tabs.Tab>
|
</Tabs.Tab>
|
||||||
{/*<Tabs.Tab value={"employees"} leftSection={<IconUsersGroup/>}>*/}
|
|
||||||
{/* Сотрудники*/}
|
|
||||||
{/*</Tabs.Tab>*/}
|
|
||||||
</Tabs.List>
|
</Tabs.List>
|
||||||
|
|
||||||
<Tabs.Panel value={"users"}>
|
<Tabs.Panel value={"users"}>
|
||||||
<motion.div
|
<motion.div
|
||||||
initial={{opacity: 0}}
|
initial={{opacity: 0}}
|
||||||
@@ -31,7 +34,6 @@ const AdminPage = () => {
|
|||||||
|
|
||||||
>
|
>
|
||||||
<UsersTab/>
|
<UsersTab/>
|
||||||
|
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</Tabs.Panel>
|
</Tabs.Panel>
|
||||||
<Tabs.Panel value={"rolesAndPositions"}>
|
<Tabs.Panel value={"rolesAndPositions"}>
|
||||||
@@ -43,6 +45,15 @@ const AdminPage = () => {
|
|||||||
<RolesAndPositionsTab/>
|
<RolesAndPositionsTab/>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</Tabs.Panel>
|
</Tabs.Panel>
|
||||||
|
<Tabs.Panel value={"finances"}>
|
||||||
|
<motion.div
|
||||||
|
initial={{opacity: 0}}
|
||||||
|
animate={{opacity: 1}}
|
||||||
|
transition={{duration: 0.2}}
|
||||||
|
>
|
||||||
|
<FinancesTab/>
|
||||||
|
</motion.div>
|
||||||
|
</Tabs.Panel>
|
||||||
|
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</PageBlock>
|
</PageBlock>
|
||||||
|
|||||||
94
src/pages/AdminPage/components/PayRateTable/PayRateTable.tsx
Normal file
94
src/pages/AdminPage/components/PayRateTable/PayRateTable.tsx
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
import {CRUDTableProps} from "../../../../types/CRUDTable.tsx";
|
||||||
|
import {PayRateSchema} from "../../../../client";
|
||||||
|
import {FC} from "react";
|
||||||
|
import {BaseTable} from "../../../../components/BaseTable/BaseTable.tsx";
|
||||||
|
import {usePayRatesTableColumns} from "./columns.tsx";
|
||||||
|
import {ActionIcon, Button, Flex, rem, Text, Tooltip} from "@mantine/core";
|
||||||
|
import {modals} from "@mantine/modals";
|
||||||
|
import {IconEdit, IconTrash} from "@tabler/icons-react";
|
||||||
|
import {MRT_TableOptions} from "mantine-react-table";
|
||||||
|
|
||||||
|
type Props = CRUDTableProps<PayRateSchema>;
|
||||||
|
|
||||||
|
const PayRateTable: FC<Props> = ({items, onCreate, onChange, onDelete}) => {
|
||||||
|
const columns = usePayRatesTableColumns();
|
||||||
|
|
||||||
|
const onCreateClick = () => {
|
||||||
|
if (!onCreate) return;
|
||||||
|
modals.openContextModal({
|
||||||
|
modal: "payRateForm",
|
||||||
|
withCloseButton: false,
|
||||||
|
innerProps: {
|
||||||
|
onCreate: onCreate
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const onEditClick = (payRate: PayRateSchema) => {
|
||||||
|
if (!onChange) return;
|
||||||
|
modals.openContextModal({
|
||||||
|
modal: "payRateForm",
|
||||||
|
withCloseButton: false,
|
||||||
|
innerProps: {
|
||||||
|
onChange: (event) => onChange({...event, id: payRate.id}),
|
||||||
|
element: payRate
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const onDeleteClick = (payRate: PayRateSchema) => {
|
||||||
|
if (!onDelete) return;
|
||||||
|
modals.openConfirmModal({
|
||||||
|
title: 'Удаление тарифа',
|
||||||
|
children: (
|
||||||
|
<Text size="sm">
|
||||||
|
Вы уверены что хотите удалить тариф {payRate.name}
|
||||||
|
</Text>
|
||||||
|
),
|
||||||
|
labels: {confirm: 'Да', cancel: "Нет"},
|
||||||
|
confirmProps: {color: 'red'},
|
||||||
|
onConfirm: () => onDelete(payRate)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<BaseTable
|
||||||
|
data={items}
|
||||||
|
columns={columns}
|
||||||
|
restProps={{
|
||||||
|
enableSorting: false,
|
||||||
|
enableColumnActions: false,
|
||||||
|
enableTopToolbar: true,
|
||||||
|
renderTopToolbar: (
|
||||||
|
<Flex p={rem(10)}>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
variant={"default"}
|
||||||
|
onClick={() => onCreateClick()}
|
||||||
|
>
|
||||||
|
Создать тариф
|
||||||
|
</Button>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
),
|
||||||
|
enableRowActions: true,
|
||||||
|
renderRowActions: ({row}) => (
|
||||||
|
<Flex gap="md">
|
||||||
|
<Tooltip label="Редактировать">
|
||||||
|
<ActionIcon
|
||||||
|
onClick={() => onEditClick(row.original)}
|
||||||
|
variant={"default"}>
|
||||||
|
<IconEdit/>
|
||||||
|
</ActionIcon>
|
||||||
|
</Tooltip>
|
||||||
|
<Tooltip label="Удалить">
|
||||||
|
<ActionIcon onClick={() => onDeleteClick(row.original)} variant={"default"}>
|
||||||
|
<IconTrash/>
|
||||||
|
</ActionIcon>
|
||||||
|
</Tooltip>
|
||||||
|
</Flex>
|
||||||
|
)
|
||||||
|
} as MRT_TableOptions<PayRateSchema>}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PayRateTable;
|
||||||
32
src/pages/AdminPage/components/PayRateTable/columns.tsx
Normal file
32
src/pages/AdminPage/components/PayRateTable/columns.tsx
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import {useMemo} from "react";
|
||||||
|
import {MRT_ColumnDef} from "mantine-react-table";
|
||||||
|
import {PayRateSchema} from "../../../../client";
|
||||||
|
|
||||||
|
export const usePayRatesTableColumns = () => {
|
||||||
|
return useMemo<MRT_ColumnDef<PayRateSchema>[]>(() => [
|
||||||
|
{
|
||||||
|
accessorKey: "name",
|
||||||
|
header: "Название тарифа"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "payrollScheme.name",
|
||||||
|
header: "Система оплаты"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "baseRate",
|
||||||
|
header: "Базовая ставка",
|
||||||
|
Cell: ({row}) => `${row.original.baseRate.toLocaleString("ru")}₽`
|
||||||
|
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "overtimeThreshold",
|
||||||
|
header: "Порог сверхурочных"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "overtimeRate",
|
||||||
|
header: "Сверхурочная ставка",
|
||||||
|
Cell: ({row}) => row.original.overtimeRate && `${row.original.overtimeRate.toLocaleString("ru")}₽`
|
||||||
|
|
||||||
|
}
|
||||||
|
], []);
|
||||||
|
}
|
||||||
@@ -0,0 +1,123 @@
|
|||||||
|
import {FC, useEffect, useState} from "react";
|
||||||
|
import {ActionIcon, Button, Flex, Pagination, rem, Text, Tooltip} from "@mantine/core";
|
||||||
|
import {usePaymentRecordsList} from "../../../../hooks/usePaymentRecordsList.tsx";
|
||||||
|
import {BaseTable} from "../../../../components/BaseTable/BaseTable.tsx";
|
||||||
|
import {usePaymentRecordsTableColumns} from "./columns.tsx";
|
||||||
|
import {modals} from "@mantine/modals";
|
||||||
|
import {PaymentRecordCreateSchema, PaymentRecordGetSchema, PayrollService} from "../../../../client";
|
||||||
|
import {notifications} from "../../../../shared/lib/notifications.ts";
|
||||||
|
import {IconTrash} from "@tabler/icons-react";
|
||||||
|
import {MRT_TableOptions} from "mantine-react-table";
|
||||||
|
import {formatDate} from "../../../../types/utils.ts";
|
||||||
|
|
||||||
|
const PaymentRecordsTable: FC = () => {
|
||||||
|
const [totalPages, setTotalPages] = useState(10);
|
||||||
|
const [page, setPage] = useState(1);
|
||||||
|
const {
|
||||||
|
pagination: paginationInfo,
|
||||||
|
objects: paymentRecords,
|
||||||
|
refetch
|
||||||
|
} = usePaymentRecordsList({page: page, itemsPerPage: 10});
|
||||||
|
useEffect(() => {
|
||||||
|
if (!paginationInfo) return;
|
||||||
|
setTotalPages(paginationInfo.totalPages);
|
||||||
|
}, [paginationInfo]);
|
||||||
|
|
||||||
|
const onCreate = (request: PaymentRecordCreateSchema) => {
|
||||||
|
PayrollService.createPaymentRecord({
|
||||||
|
requestBody: {
|
||||||
|
data: request
|
||||||
|
}
|
||||||
|
}).then(async ({ok, message}) => {
|
||||||
|
notifications.guess(ok, {message});
|
||||||
|
if (!ok) return;
|
||||||
|
await refetch();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const onCreateClick = () => {
|
||||||
|
modals.openContextModal({
|
||||||
|
modal: "createPaymentRecord",
|
||||||
|
title: "Создание начисления",
|
||||||
|
innerProps: {
|
||||||
|
onCreate: onCreate
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const onDelete = (record: PaymentRecordGetSchema) => {
|
||||||
|
PayrollService.deletePaymentRecord({
|
||||||
|
requestBody: {
|
||||||
|
paymentRecordId: record.id
|
||||||
|
}
|
||||||
|
}).then(async ({ok, message}) => {
|
||||||
|
notifications.guess(ok, {message});
|
||||||
|
if (!ok) return;
|
||||||
|
await refetch();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const onDeleteClick = (record: PaymentRecordGetSchema) => {
|
||||||
|
modals.openConfirmModal({
|
||||||
|
title: 'Удаление начисления',
|
||||||
|
children: (
|
||||||
|
<Text size="sm">
|
||||||
|
Вы уверены что хотите удалить начисление
|
||||||
|
пользователю {record.user.firstName} {record.user.secondName} от {formatDate(record.createdAt)}
|
||||||
|
</Text>
|
||||||
|
),
|
||||||
|
labels: {confirm: 'Да', cancel: "Нет"},
|
||||||
|
confirmProps: {color: 'red'},
|
||||||
|
onConfirm: () => onDelete(record)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const columns = usePaymentRecordsTableColumns();
|
||||||
|
return (
|
||||||
|
<Flex
|
||||||
|
direction={"column"}
|
||||||
|
h={"100%"}
|
||||||
|
gap={rem(10)}
|
||||||
|
>
|
||||||
|
<BaseTable
|
||||||
|
data={paymentRecords}
|
||||||
|
columns={columns}
|
||||||
|
restProps={{
|
||||||
|
enableSorting: false,
|
||||||
|
enableColumnActions: false,
|
||||||
|
enableTopToolbar: true,
|
||||||
|
renderTopToolbar: (
|
||||||
|
<Flex p={rem(10)}>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
variant={"default"}
|
||||||
|
onClick={() => onCreateClick()}
|
||||||
|
>
|
||||||
|
Создать начисление
|
||||||
|
</Button>
|
||||||
|
</Flex>
|
||||||
|
),
|
||||||
|
enableRowActions: true,
|
||||||
|
renderRowActions: ({row}) => (
|
||||||
|
<Flex gap="md">
|
||||||
|
|
||||||
|
<Tooltip label="Удалить">
|
||||||
|
<ActionIcon onClick={() => onDeleteClick(row.original)} variant={"default"}>
|
||||||
|
<IconTrash/>
|
||||||
|
</ActionIcon>
|
||||||
|
</Tooltip>
|
||||||
|
</Flex>
|
||||||
|
)
|
||||||
|
} as MRT_TableOptions<PaymentRecordGetSchema>}
|
||||||
|
/>
|
||||||
|
{totalPages > 1 &&
|
||||||
|
|
||||||
|
<Pagination
|
||||||
|
style={{alignSelf: "flex-end"}}
|
||||||
|
withEdges
|
||||||
|
onChange={event => setPage(event)}
|
||||||
|
value={page}
|
||||||
|
total={totalPages}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
|
||||||
|
</Flex>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default PaymentRecordsTable;
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
import {useMemo} from "react";
|
||||||
|
import {MRT_ColumnDef} from "mantine-react-table";
|
||||||
|
import {PaymentRecordGetSchema} from "../../../../client";
|
||||||
|
import {PaySchemeType} from "../../../../shared/enums/PaySchemeType.ts";
|
||||||
|
import {getPluralForm} from "../../../../shared/lib/utils.ts";
|
||||||
|
import {formatDate} from "../../../../types/utils.ts";
|
||||||
|
import {isEqual} from "lodash";
|
||||||
|
|
||||||
|
export const usePaymentRecordsTableColumns = () => {
|
||||||
|
const getWorkUnitsText = (paymentRecord: PaymentRecordGetSchema) => {
|
||||||
|
const payrollScheme = paymentRecord.payrollScheme;
|
||||||
|
if (payrollScheme.key === PaySchemeType.HOURLY) {
|
||||||
|
return getPluralForm(paymentRecord.workUnits, "час", "часа", "часов")
|
||||||
|
} else if (
|
||||||
|
payrollScheme.key === PaySchemeType.DAILY
|
||||||
|
) {
|
||||||
|
return getPluralForm(paymentRecord.workUnits, "день", "дня", "дней")
|
||||||
|
} else if (
|
||||||
|
payrollScheme.key === PaySchemeType.MONTHLY
|
||||||
|
) {
|
||||||
|
return getPluralForm(paymentRecord.workUnits, "месяц", "месяца", "месяцев");
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
const getDateRangesText = (paymentRecord: PaymentRecordGetSchema) => {
|
||||||
|
if (paymentRecord.endDate && !isEqual(paymentRecord.startDate, paymentRecord.endDate)) {
|
||||||
|
return `${formatDate(paymentRecord.startDate)} - ${formatDate(paymentRecord.endDate)}`
|
||||||
|
}
|
||||||
|
return `${formatDate(paymentRecord.startDate)}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return useMemo<MRT_ColumnDef<PaymentRecordGetSchema>[]>(() => [
|
||||||
|
{
|
||||||
|
header: "Дата начисления",
|
||||||
|
Cell: ({row}) => new Date(row.original.createdAt).toLocaleString('ru-RU')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: "Получил начисление",
|
||||||
|
Cell: ({row}) => `${row.original.user.firstName} ${row.original.user.secondName}`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: "Создал начисление",
|
||||||
|
Cell: ({row}) => `${row.original.createdByUser.firstName} ${row.original.createdByUser.secondName}`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: "Количество",
|
||||||
|
Cell: ({row}) => `${row.original.workUnits} ${getWorkUnitsText(row.original)}`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: "Сумма начисления",
|
||||||
|
Cell: ({row}) => row.original.amount.toLocaleString("ru-RU")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: "Временной промежуток",
|
||||||
|
Cell: ({row}) => getDateRangesText(row.original)
|
||||||
|
}
|
||||||
|
], [])
|
||||||
|
}
|
||||||
@@ -52,13 +52,7 @@ const UsersTable: FC<Props> = ({items, onChange, onDelete}) => {
|
|||||||
enableRowActions: true,
|
enableRowActions: true,
|
||||||
renderRowActions: ({row}) => (
|
renderRowActions: ({row}) => (
|
||||||
<Flex gap="md">
|
<Flex gap="md">
|
||||||
<Tooltip onClick={() => {
|
|
||||||
onDeleteClick(row.original);
|
|
||||||
}} label="Удалить">
|
|
||||||
<ActionIcon variant={"default"}>
|
|
||||||
<IconTrash/>
|
|
||||||
</ActionIcon>
|
|
||||||
</Tooltip>
|
|
||||||
<Tooltip
|
<Tooltip
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
onEditClick(row.original)
|
onEditClick(row.original)
|
||||||
@@ -69,6 +63,13 @@ const UsersTable: FC<Props> = ({items, onChange, onDelete}) => {
|
|||||||
<IconEdit/>
|
<IconEdit/>
|
||||||
</ActionIcon>
|
</ActionIcon>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
<Tooltip onClick={() => {
|
||||||
|
onDeleteClick(row.original);
|
||||||
|
}} label="Удалить">
|
||||||
|
<ActionIcon variant={"default"}>
|
||||||
|
<IconTrash/>
|
||||||
|
</ActionIcon>
|
||||||
|
</Tooltip>
|
||||||
</Flex>
|
</Flex>
|
||||||
),
|
),
|
||||||
} as MRT_TableOptions<UserSchema>}
|
} as MRT_TableOptions<UserSchema>}
|
||||||
|
|||||||
@@ -5,17 +5,10 @@ import {IconCheck, IconX} from "@tabler/icons-react";
|
|||||||
|
|
||||||
export const useUsersTableColumns = () => {
|
export const useUsersTableColumns = () => {
|
||||||
return useMemo<MRT_ColumnDef<UserSchema>[]>(() => [
|
return useMemo<MRT_ColumnDef<UserSchema>[]>(() => [
|
||||||
|
|
||||||
{
|
{
|
||||||
accessorKey: "firstName",
|
header: "ФИО",
|
||||||
header: "Имя"
|
Cell: ({row}) => `${row.original.firstName} ${row.original.secondName}`
|
||||||
},
|
|
||||||
{
|
|
||||||
accessorKey: "secondName",
|
|
||||||
header: "Фамилия"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
accessorKey: "telegramId",
|
|
||||||
header: "ID Телеграм"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: "phoneNumber",
|
accessorKey: "phoneNumber",
|
||||||
@@ -25,6 +18,14 @@ export const useUsersTableColumns = () => {
|
|||||||
accessorKey: "role.name",
|
accessorKey: "role.name",
|
||||||
header: "Роль"
|
header: "Роль"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "position.name",
|
||||||
|
header: "Должность"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "payRate.name",
|
||||||
|
header: "Тариф"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
accessorKey: "comment",
|
accessorKey: "comment",
|
||||||
header: "Дополнительная информация"
|
header: "Дополнительная информация"
|
||||||
|
|||||||
9
src/pages/AdminPage/hooks/usePayRatesList.tsx
Normal file
9
src/pages/AdminPage/hooks/usePayRatesList.tsx
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import {PayrollService} from "../../../client";
|
||||||
|
import ObjectList from "../../../hooks/objectList.tsx";
|
||||||
|
|
||||||
|
const usePayRatesList = () => ObjectList({
|
||||||
|
queryFn: PayrollService.getAllPayRates,
|
||||||
|
getObjectsFn: response => response.payRates,
|
||||||
|
queryKey: "getAllPayRates"
|
||||||
|
})
|
||||||
|
export default usePayRatesList;
|
||||||
@@ -0,0 +1,130 @@
|
|||||||
|
import BaseFormModal, {CreateProps} from "../../../ClientsPage/modals/BaseFormModal/BaseFormModal.tsx";
|
||||||
|
import {PaymentRecordCreateSchema} from "../../../../client";
|
||||||
|
import {ContextModalProps} from "@mantine/modals";
|
||||||
|
import {useForm} from "@mantine/form";
|
||||||
|
import {Flex, NumberInput, rem} from "@mantine/core";
|
||||||
|
import {DatePickerInput, MonthPickerInput} from "@mantine/dates";
|
||||||
|
import {useEffect, useState} from "react";
|
||||||
|
import {dateWithoutTimezone} from "../../../../shared/lib/utils.ts";
|
||||||
|
import UserSelect from "../../../../components/Selects/UserSelect/UserSelect.tsx";
|
||||||
|
import {PaySchemeType} from "../../../../shared/enums/PaySchemeType.ts";
|
||||||
|
import {motion} from "framer-motion";
|
||||||
|
|
||||||
|
type Props = CreateProps<PaymentRecordCreateSchema>;
|
||||||
|
const CreatePaymentRecordModal = ({
|
||||||
|
context,
|
||||||
|
id,
|
||||||
|
innerProps
|
||||||
|
}: ContextModalProps<Props>) => {
|
||||||
|
const form = useForm<Partial<PaymentRecordCreateSchema>>({
|
||||||
|
validate: {
|
||||||
|
user: (user) => !user && "Необходимо выбрать сотрудника",
|
||||||
|
startDate: (startDate) => !startDate && "Необходимо указать временной промежуток",
|
||||||
|
workUnits: (workUnits) => !workUnits && "Укажите количество"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const [dateRange, setDateRange] = useState<[Date | null, Date | null]>([null, null]);
|
||||||
|
useEffect(() => {
|
||||||
|
|
||||||
|
const setDates = (start: string | undefined, end: string | undefined) => {
|
||||||
|
form.setFieldValue("startDate", start);
|
||||||
|
form.setFieldValue("endDate", end);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (dateRange.every(dr => dr == null)) {
|
||||||
|
setDates(undefined, undefined);
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
const notNullValues = dateRange.filter((dr): dr is Date => dr !== null).map(dateWithoutTimezone);
|
||||||
|
const startDate = notNullValues[0];
|
||||||
|
const endDate = notNullValues[1] || startDate;
|
||||||
|
setDates(startDate, endDate);
|
||||||
|
}
|
||||||
|
}, [dateRange]);
|
||||||
|
|
||||||
|
const getDateRangeInput = () => {
|
||||||
|
if (!form.values.user) return <></>
|
||||||
|
const payRate = form.values.user.payRate;
|
||||||
|
if (!payRate) return <></>;
|
||||||
|
if (payRate.payrollScheme.key == PaySchemeType.MONTHLY)
|
||||||
|
return (
|
||||||
|
<MonthPickerInput
|
||||||
|
error={form.getInputProps("startDate").error}
|
||||||
|
|
||||||
|
label={"Временной промежуток"}
|
||||||
|
placeholder={"Выберите временной промежуток"}
|
||||||
|
type={"range"}
|
||||||
|
value={dateRange}
|
||||||
|
onChange={setDateRange}
|
||||||
|
allowSingleDateInRange
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
return (<DatePickerInput
|
||||||
|
error={form.getInputProps("startDate").error}
|
||||||
|
label={"Временной промежуток"}
|
||||||
|
placeholder={"Выберите временной промежуток"}
|
||||||
|
type={"range"}
|
||||||
|
allowSingleDateInRange
|
||||||
|
value={dateRange}
|
||||||
|
onChange={setDateRange}
|
||||||
|
/>);
|
||||||
|
}
|
||||||
|
const getAmountLabel = () => {
|
||||||
|
const user = form.values.user;
|
||||||
|
if (!user) return "";
|
||||||
|
const payRate = user?.payRate;
|
||||||
|
if (!payRate) return "";
|
||||||
|
if (payRate.payrollScheme.key == PaySchemeType.HOURLY) return "Количество часов";
|
||||||
|
if (payRate.payrollScheme.key == PaySchemeType.MONTHLY) return "Количество месяцев";
|
||||||
|
if (payRate.payrollScheme.key == PaySchemeType.DAILY) return "Количество дней";
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
const getAmountPlaceholder = () => {
|
||||||
|
return "Укажите " + getAmountLabel().toLowerCase();
|
||||||
|
}
|
||||||
|
return (<BaseFormModal
|
||||||
|
form={form}
|
||||||
|
closeOnSubmit
|
||||||
|
onClose={() => context.closeContextModal(id)}
|
||||||
|
{...innerProps}
|
||||||
|
>
|
||||||
|
<BaseFormModal.Body>
|
||||||
|
<>
|
||||||
|
<Flex direction={"column"} gap={rem(10)}>
|
||||||
|
<UserSelect
|
||||||
|
label={"Сотрудник"}
|
||||||
|
placeholder={"Выберите сотрудника"}
|
||||||
|
searchable
|
||||||
|
filterBy={(user) => !!user.payRate}
|
||||||
|
{...form.getInputProps("user")}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{form.values.user &&
|
||||||
|
<>
|
||||||
|
<motion.div
|
||||||
|
|
||||||
|
initial={{opacity: 0}}
|
||||||
|
animate={{opacity: 1}}
|
||||||
|
transition={{duration: 0.3}}
|
||||||
|
>
|
||||||
|
<Flex
|
||||||
|
direction={"column"}
|
||||||
|
gap={rem(10)}>
|
||||||
|
|
||||||
|
{getDateRangeInput()}
|
||||||
|
<NumberInput
|
||||||
|
label={getAmountLabel()}
|
||||||
|
placeholder={getAmountPlaceholder()}
|
||||||
|
hideControls
|
||||||
|
{...form.getInputProps("workUnits")}
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
</motion.div>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
</Flex>
|
||||||
|
</>
|
||||||
|
</BaseFormModal.Body>
|
||||||
|
</BaseFormModal>)
|
||||||
|
}
|
||||||
|
export default CreatePaymentRecordModal;
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
import BaseFormModal, {CreateEditFormProps} from "../../../ClientsPage/modals/BaseFormModal/BaseFormModal.tsx";
|
||||||
|
import {PayRateSchemaBase} from "../../../../client";
|
||||||
|
import {ContextModalProps} from "@mantine/modals";
|
||||||
|
import {useForm} from "@mantine/form";
|
||||||
|
import {Fieldset, Flex, NumberInput, rem, TextInput} from "@mantine/core";
|
||||||
|
import PayrollSchemeSelect from "../../../../components/Selects/PayrollSchemeSelect/PayrollSchemeSelect.tsx";
|
||||||
|
import {PaySchemeType} from "../../../../shared/enums/PaySchemeType.ts";
|
||||||
|
|
||||||
|
type Props = CreateEditFormProps<PayRateSchemaBase>
|
||||||
|
|
||||||
|
const PayRateFormModal = ({
|
||||||
|
context,
|
||||||
|
id,
|
||||||
|
innerProps
|
||||||
|
}: ContextModalProps<Props>) => {
|
||||||
|
const isEditing = 'element' in innerProps;
|
||||||
|
const initialValue: Partial<PayRateSchemaBase> = isEditing ? innerProps.element : {};
|
||||||
|
|
||||||
|
const form = useForm<Partial<PayRateSchemaBase>>({
|
||||||
|
initialValues: initialValue,
|
||||||
|
validate: {
|
||||||
|
name: (name) => !name && "Необходимо указать название тарифа",
|
||||||
|
payrollScheme: (scheme) => !scheme && "Необходимо выбрать систему оплаты",
|
||||||
|
baseRate: (baseRate) => !baseRate && "Небходимо указать базовую ставку"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
<BaseFormModal
|
||||||
|
form={form}
|
||||||
|
closeOnSubmit
|
||||||
|
onClose={() => context.closeContextModal(id)}
|
||||||
|
{...innerProps}
|
||||||
|
>
|
||||||
|
<BaseFormModal.Body>
|
||||||
|
<>
|
||||||
|
<Fieldset legend={"Общие параметры"}>
|
||||||
|
<Flex direction={"column"} gap={rem(10)}>
|
||||||
|
|
||||||
|
<TextInput
|
||||||
|
label={"Название"}
|
||||||
|
placeholder={"Введите название тарифа"}
|
||||||
|
{...form.getInputProps("name")}
|
||||||
|
/>
|
||||||
|
<PayrollSchemeSelect
|
||||||
|
label={"Система оплаты"}
|
||||||
|
placeholder={"Выберите систему оплаты"}
|
||||||
|
{...form.getInputProps("payrollScheme")}
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
</Fieldset>
|
||||||
|
<Fieldset>
|
||||||
|
<Flex direction={"column"} gap={rem(10)}>
|
||||||
|
|
||||||
|
<NumberInput
|
||||||
|
allowNegative={false}
|
||||||
|
hideControls
|
||||||
|
decimalScale={2}
|
||||||
|
label={"Базовая ставка"}
|
||||||
|
placeholder={"Выберите базовую ставку"}
|
||||||
|
thousandSeparator={" "}
|
||||||
|
suffix={"₽"}
|
||||||
|
{...form.getInputProps("baseRate")}
|
||||||
|
|
||||||
|
/>
|
||||||
|
{form.values.payrollScheme?.key === PaySchemeType.HOURLY &&
|
||||||
|
<>
|
||||||
|
<NumberInput
|
||||||
|
allowNegative={false}
|
||||||
|
hideControls
|
||||||
|
allowDecimal={false}
|
||||||
|
label={"Порог сверхурочных"}
|
||||||
|
placeholder={"Введите порог сверхурочных"}
|
||||||
|
{...form.getInputProps("overtimeThreshold")}
|
||||||
|
/>
|
||||||
|
<NumberInput
|
||||||
|
allowNegative={false}
|
||||||
|
hideControls
|
||||||
|
decimalScale={2}
|
||||||
|
label={"Сверхурочная ставка"}
|
||||||
|
placeholder={"Выберите сверхурочную ставку"}
|
||||||
|
thousandSeparator={" "}
|
||||||
|
suffix={"₽"}
|
||||||
|
{...form.getInputProps("overtimeRate")}
|
||||||
|
/>
|
||||||
|
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
</Fieldset>
|
||||||
|
</>
|
||||||
|
</BaseFormModal.Body>
|
||||||
|
</BaseFormModal>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PayRateFormModal;
|
||||||
@@ -9,6 +9,7 @@ import {UserRoleEnum} from "../../../../shared/enums/UserRole.ts";
|
|||||||
import {capitalize} from "lodash";
|
import {capitalize} from "lodash";
|
||||||
import {IMaskInput} from "react-imask";
|
import {IMaskInput} from "react-imask";
|
||||||
import phone from "phone";
|
import phone from "phone";
|
||||||
|
import PayRateSelect from "../../../../components/Selects/PayRateSelect/PayRateSelect.tsx";
|
||||||
|
|
||||||
type Props = EditProps<UserSchema>;
|
type Props = EditProps<UserSchema>;
|
||||||
const UserFormModal = ({context, id, innerProps}: ContextModalProps<Props>) => {
|
const UserFormModal = ({context, id, innerProps}: ContextModalProps<Props>) => {
|
||||||
@@ -65,21 +66,27 @@ const UserFormModal = ({context, id, innerProps}: ContextModalProps<Props>) => {
|
|||||||
</Fieldset>
|
</Fieldset>
|
||||||
<Fieldset legend={"Роль и должность"}>
|
<Fieldset legend={"Роль и должность"}>
|
||||||
<Stack>
|
<Stack>
|
||||||
|
|
||||||
<RoleSelect
|
<RoleSelect
|
||||||
label={"Роль пользователя"}
|
label={"Роль пользователя"}
|
||||||
placeholder={"Выберите роль пользователя"}
|
placeholder={"Выберите роль пользователя"}
|
||||||
{...form.getInputProps('role')}
|
{...form.getInputProps('role')}
|
||||||
/>
|
/>
|
||||||
{form.values.role.key === UserRoleEnum.EMPLOYEE &&
|
{form.values.role.key === UserRoleEnum.EMPLOYEE &&
|
||||||
<PositionSelect
|
<>
|
||||||
label={"Должность сотрудника"}
|
<PositionSelect
|
||||||
placeholder={"Выберите должность сотрудника"}
|
label={"Должность сотрудника"}
|
||||||
{...form.getInputProps('position')}
|
placeholder={"Выберите должность сотрудника"}
|
||||||
/>
|
{...form.getInputProps('position')}
|
||||||
|
/>
|
||||||
|
<PayRateSelect
|
||||||
|
label={"Тариф"}
|
||||||
|
placeholder={"Выберите тариф сотрудника"}
|
||||||
|
{...form.getInputProps("payRate")}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
|
||||||
}
|
}
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
</Fieldset>
|
</Fieldset>
|
||||||
<Fieldset legend={"Дополнительные параметры"}>
|
<Fieldset legend={"Дополнительные параметры"}>
|
||||||
<Stack>
|
<Stack>
|
||||||
|
|||||||
97
src/pages/AdminPage/tabs/Finances/FinancesTab.tsx
Normal file
97
src/pages/AdminPage/tabs/Finances/FinancesTab.tsx
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
import {Tabs} from "@mantine/core";
|
||||||
|
import {IconBusinessplan, IconHistory} from "@tabler/icons-react";
|
||||||
|
import {motion} from "framer-motion";
|
||||||
|
import PayRateTable from "../../components/PayRateTable/PayRateTable.tsx";
|
||||||
|
import usePayRatesList from "../../hooks/usePayRatesList.tsx";
|
||||||
|
import {CRUDTableProps} from "../../../../types/CRUDTable.tsx";
|
||||||
|
import {PayRateSchema, PayRateSchemaBase, PayrollService} from "../../../../client";
|
||||||
|
import {notifications} from "../../../../shared/lib/notifications.ts";
|
||||||
|
import PaymentRecordsTable from "../../components/PaymentRecordsTable/PaymentRecordsTable.tsx";
|
||||||
|
|
||||||
|
const payRateTableState = (): CRUDTableProps<PayRateSchema> => {
|
||||||
|
const {objects: items, refetch} = usePayRatesList();
|
||||||
|
const onCreate = (item: PayRateSchemaBase) => {
|
||||||
|
PayrollService.createPayRate({
|
||||||
|
requestBody: {
|
||||||
|
data: item
|
||||||
|
}
|
||||||
|
}).then(async ({ok, message}) => {
|
||||||
|
notifications.guess(ok, {message});
|
||||||
|
if (!ok) return;
|
||||||
|
await refetch();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const onChange = (item: PayRateSchema) => {
|
||||||
|
PayrollService.updatePayRate({
|
||||||
|
requestBody: {
|
||||||
|
data: item
|
||||||
|
}
|
||||||
|
}).then(async ({ok, message}) => {
|
||||||
|
notifications.guess(ok, {message});
|
||||||
|
if (!ok) return;
|
||||||
|
await refetch();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const onDelete = (item: PayRateSchema) => {
|
||||||
|
PayrollService.deletePayRate({
|
||||||
|
requestBody: {
|
||||||
|
payRateId: item.id
|
||||||
|
}
|
||||||
|
}).then(async ({ok, message}) => {
|
||||||
|
notifications.guess(ok, {message});
|
||||||
|
if (!ok) return;
|
||||||
|
await refetch();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return {items, onCreate, onChange, onDelete};
|
||||||
|
}
|
||||||
|
|
||||||
|
const FinancesTab = () => {
|
||||||
|
const payRateState = payRateTableState();
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Tabs
|
||||||
|
keepMounted={false}
|
||||||
|
defaultValue={"paymentRecords"}
|
||||||
|
color={"gray.6"}
|
||||||
|
>
|
||||||
|
<Tabs.List
|
||||||
|
justify={"center"}
|
||||||
|
grow
|
||||||
|
>
|
||||||
|
<Tabs.Tab value={"paymentRecords"} leftSection={<IconHistory/>}>
|
||||||
|
Начисления
|
||||||
|
</Tabs.Tab>
|
||||||
|
<Tabs.Tab value={"tariffs"} leftSection={<IconBusinessplan/>}>
|
||||||
|
Тарифы
|
||||||
|
</Tabs.Tab>
|
||||||
|
</Tabs.List>
|
||||||
|
<Tabs.Panel value={"tariffs"}>
|
||||||
|
<motion.div
|
||||||
|
initial={{opacity: 0}}
|
||||||
|
animate={{opacity: 1}}
|
||||||
|
transition={{duration: 0.2}}
|
||||||
|
|
||||||
|
>
|
||||||
|
<PayRateTable
|
||||||
|
{...payRateState}
|
||||||
|
/>
|
||||||
|
</motion.div>
|
||||||
|
</Tabs.Panel>
|
||||||
|
<Tabs.Panel value={"paymentRecords"}>
|
||||||
|
<motion.div
|
||||||
|
initial={{opacity: 0}}
|
||||||
|
animate={{opacity: 1}}
|
||||||
|
transition={{duration: 0.2}}
|
||||||
|
>
|
||||||
|
<PaymentRecordsTable/>
|
||||||
|
</motion.div>
|
||||||
|
</Tabs.Panel>
|
||||||
|
|
||||||
|
|
||||||
|
</Tabs>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FinancesTab
|
||||||
@@ -1,7 +1,4 @@
|
|||||||
import {createLazyFileRoute} from "@tanstack/react-router";
|
import {createLazyFileRoute} from "@tanstack/react-router";
|
||||||
import {Button} from '@mantine/core';
|
|
||||||
import {modals} from "@mantine/modals";
|
|
||||||
import BaseMarketplaceSelect from "../components/Selects/BaseMarketplaceSelect/BaseMarketplaceSelect.tsx";
|
|
||||||
|
|
||||||
export const Route = createLazyFileRoute('/test')({
|
export const Route = createLazyFileRoute('/test')({
|
||||||
component: TestPage
|
component: TestPage
|
||||||
@@ -9,12 +6,9 @@ export const Route = createLazyFileRoute('/test')({
|
|||||||
|
|
||||||
|
|
||||||
function TestPage() {
|
function TestPage() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<BaseMarketplaceSelect
|
|
||||||
onChange={() => {
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
5
src/shared/enums/PaySchemeType.ts
Normal file
5
src/shared/enums/PaySchemeType.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
export enum PaySchemeType {
|
||||||
|
HOURLY = 'hourly',
|
||||||
|
DAILY = 'daily',
|
||||||
|
MONTHLY = 'monthly'
|
||||||
|
}
|
||||||
4
src/types/Pagination.ts
Normal file
4
src/types/Pagination.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
export type Pagination = {
|
||||||
|
itemsPerPage: number,
|
||||||
|
page: number
|
||||||
|
}
|
||||||
@@ -8,3 +8,6 @@ export type BaseFormInputProps<T> = {
|
|||||||
value: T;
|
value: T;
|
||||||
error?: string | null;
|
error?: string | null;
|
||||||
}
|
}
|
||||||
|
export const formatDate = (date: string) => {
|
||||||
|
return new Date(date).toLocaleDateString("ru-RU");
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user