Add timeline tracking features with database schema updates
- Introduced new tables `timeline_footprints` and `timeline_activities` to manage employee location data and activity records. - Updated `company_settings` to include `gps_interval_seconds` and `checkout_warning_radius_meters` for enhanced tracking configuration. - Implemented foreign key constraints to ensure data integrity between new tables and existing `employees`, `customers`, and `visits` tables. - Created services and controllers for handling timeline activities and footprints, including ingestion and retrieval of data. - Enhanced DTOs and validation logic to support new fields and ensure correct data formats in API requests. - Added unit and integration tests to validate the new functionalities and ensure proper handling of timeline records. - Created migration scripts to apply the necessary database schema changes for the new features.
This commit is contained in:
@@ -1,10 +1,13 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { EmployeesModule } from '../employees/employees.module';
|
||||
import { TimelineModule } from '../../field/timeline/timeline.module';
|
||||
import { CustomersReadController } from './customers-read.controller';
|
||||
import { CustomersWriteController } from './customers-write.controller';
|
||||
import { CustomersRepository } from './customers.repository';
|
||||
import { CustomersService } from './customers.service';
|
||||
|
||||
@Module({
|
||||
imports: [EmployeesModule, TimelineModule],
|
||||
controllers: [CustomersReadController, CustomersWriteController],
|
||||
providers: [CustomersRepository, CustomersService],
|
||||
exports: [CustomersService],
|
||||
|
||||
@@ -29,6 +29,8 @@ import {
|
||||
parseCsvRecord,
|
||||
} from './customer-fields';
|
||||
import { CustomersRepository } from './customers.repository';
|
||||
import { EmployeesService } from '../employees/employees.service';
|
||||
import { TimelineActivitiesService } from '../../field/timeline/timeline-activities.service';
|
||||
|
||||
export type ListCustomersQuery = {
|
||||
readonly code?: string;
|
||||
@@ -73,7 +75,11 @@ const CSV_REQUIRED_HEADERS = ['code', 'name', 'phone', 'address'] as const;
|
||||
|
||||
@Injectable()
|
||||
export class CustomersService {
|
||||
constructor(private readonly customersRepository: CustomersRepository) {}
|
||||
constructor(
|
||||
private readonly customersRepository: CustomersRepository,
|
||||
private readonly employeesService: EmployeesService,
|
||||
private readonly timelineActivitiesService: TimelineActivitiesService,
|
||||
) {}
|
||||
|
||||
async list(
|
||||
query: ListCustomersQuery,
|
||||
@@ -133,6 +139,16 @@ export class CustomersService {
|
||||
const created = await this.customersRepository.create(
|
||||
this.toCreateInput(input),
|
||||
);
|
||||
const employee = await this.employeesService.requireByUserId(input.userId);
|
||||
await this.timelineActivitiesService.recordIfLocated({
|
||||
employeeId: employee.id,
|
||||
type: 'customer_created',
|
||||
sourceType: 'customer',
|
||||
sourceId: created.id,
|
||||
latitude: created.latitude,
|
||||
longitude: created.longitude,
|
||||
customerId: created.id,
|
||||
});
|
||||
return this.toDetail(created);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user