feat: add time entry manager, controller, and API routes
This commit is contained in:
@@ -212,6 +212,51 @@ export type ScheduleSpan = Prisma.ScheduleSpanModel
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export type Schedule = Prisma.ScheduleModel
|
export type Schedule = Prisma.ScheduleModel
|
||||||
|
/**
|
||||||
|
* Model Activity
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export type Activity = Prisma.ActivityModel
|
||||||
|
/**
|
||||||
|
* Model ActivityNotes
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export type ActivityNotes = Prisma.ActivityNotesModel
|
||||||
|
/**
|
||||||
|
* Model ActivityType
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export type ActivityType = Prisma.ActivityTypeModel
|
||||||
|
/**
|
||||||
|
* Model ActivityStatus
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export type ActivityStatus = Prisma.ActivityStatusModel
|
||||||
|
/**
|
||||||
|
* Model TimeEntry
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export type TimeEntry = Prisma.TimeEntryModel
|
||||||
|
/**
|
||||||
|
* Model TimeEntryStatus
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export type TimeEntryStatus = Prisma.TimeEntryStatusModel
|
||||||
|
/**
|
||||||
|
* Model TimeEntryChargeCode
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export type TimeEntryChargeCode = Prisma.TimeEntryChargeCodeModel
|
||||||
|
/**
|
||||||
|
* Model TimeActivityClass
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export type TimeActivityClass = Prisma.TimeActivityClassModel
|
||||||
|
/**
|
||||||
|
* Model TimeActivityType
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export type TimeActivityType = Prisma.TimeActivityTypeModel
|
||||||
/**
|
/**
|
||||||
* Model CredentialType
|
* Model CredentialType
|
||||||
*
|
*
|
||||||
@@ -242,3 +287,8 @@ export type TaxCode = Prisma.TaxCodeModel
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export type CwMember = Prisma.CwMemberModel
|
export type CwMember = Prisma.CwMemberModel
|
||||||
|
/**
|
||||||
|
* Model CwMemberType
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export type CwMemberType = Prisma.CwMemberTypeModel
|
||||||
|
|||||||
@@ -236,6 +236,51 @@ export type ScheduleSpan = Prisma.ScheduleSpanModel
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export type Schedule = Prisma.ScheduleModel
|
export type Schedule = Prisma.ScheduleModel
|
||||||
|
/**
|
||||||
|
* Model Activity
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export type Activity = Prisma.ActivityModel
|
||||||
|
/**
|
||||||
|
* Model ActivityNotes
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export type ActivityNotes = Prisma.ActivityNotesModel
|
||||||
|
/**
|
||||||
|
* Model ActivityType
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export type ActivityType = Prisma.ActivityTypeModel
|
||||||
|
/**
|
||||||
|
* Model ActivityStatus
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export type ActivityStatus = Prisma.ActivityStatusModel
|
||||||
|
/**
|
||||||
|
* Model TimeEntry
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export type TimeEntry = Prisma.TimeEntryModel
|
||||||
|
/**
|
||||||
|
* Model TimeEntryStatus
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export type TimeEntryStatus = Prisma.TimeEntryStatusModel
|
||||||
|
/**
|
||||||
|
* Model TimeEntryChargeCode
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export type TimeEntryChargeCode = Prisma.TimeEntryChargeCodeModel
|
||||||
|
/**
|
||||||
|
* Model TimeActivityClass
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export type TimeActivityClass = Prisma.TimeActivityClassModel
|
||||||
|
/**
|
||||||
|
* Model TimeActivityType
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export type TimeActivityType = Prisma.TimeActivityTypeModel
|
||||||
/**
|
/**
|
||||||
* Model CredentialType
|
* Model CredentialType
|
||||||
*
|
*
|
||||||
@@ -266,3 +311,8 @@ export type TaxCode = Prisma.TaxCodeModel
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export type CwMember = Prisma.CwMemberModel
|
export type CwMember = Prisma.CwMemberModel
|
||||||
|
/**
|
||||||
|
* Model CwMemberType
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export type CwMemberType = Prisma.CwMemberTypeModel
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@@ -90,12 +90,22 @@ export const ModelName = {
|
|||||||
ScheduleType: 'ScheduleType',
|
ScheduleType: 'ScheduleType',
|
||||||
ScheduleSpan: 'ScheduleSpan',
|
ScheduleSpan: 'ScheduleSpan',
|
||||||
Schedule: 'Schedule',
|
Schedule: 'Schedule',
|
||||||
|
Activity: 'Activity',
|
||||||
|
ActivityNotes: 'ActivityNotes',
|
||||||
|
ActivityType: 'ActivityType',
|
||||||
|
ActivityStatus: 'ActivityStatus',
|
||||||
|
TimeEntry: 'TimeEntry',
|
||||||
|
TimeEntryStatus: 'TimeEntryStatus',
|
||||||
|
TimeEntryChargeCode: 'TimeEntryChargeCode',
|
||||||
|
TimeActivityClass: 'TimeActivityClass',
|
||||||
|
TimeActivityType: 'TimeActivityType',
|
||||||
CredentialType: 'CredentialType',
|
CredentialType: 'CredentialType',
|
||||||
SecureValue: 'SecureValue',
|
SecureValue: 'SecureValue',
|
||||||
Credential: 'Credential',
|
Credential: 'Credential',
|
||||||
GeneratedQuotes: 'GeneratedQuotes',
|
GeneratedQuotes: 'GeneratedQuotes',
|
||||||
TaxCode: 'TaxCode',
|
TaxCode: 'TaxCode',
|
||||||
CwMember: 'CwMember'
|
CwMember: 'CwMember',
|
||||||
|
CwMemberType: 'CwMemberType'
|
||||||
} as const
|
} as const
|
||||||
|
|
||||||
export type ModelName = (typeof ModelName)[keyof typeof ModelName]
|
export type ModelName = (typeof ModelName)[keyof typeof ModelName]
|
||||||
@@ -888,6 +898,204 @@ export const ScheduleScalarFieldEnum = {
|
|||||||
export type ScheduleScalarFieldEnum = (typeof ScheduleScalarFieldEnum)[keyof typeof ScheduleScalarFieldEnum]
|
export type ScheduleScalarFieldEnum = (typeof ScheduleScalarFieldEnum)[keyof typeof ScheduleScalarFieldEnum]
|
||||||
|
|
||||||
|
|
||||||
|
export const ActivityScalarFieldEnum = {
|
||||||
|
id: 'id',
|
||||||
|
uid: 'uid',
|
||||||
|
subject: 'subject',
|
||||||
|
startTime: 'startTime',
|
||||||
|
endTime: 'endTime',
|
||||||
|
assignToId: 'assignToId',
|
||||||
|
assignedById: 'assignedById',
|
||||||
|
enteredBy: 'enteredBy',
|
||||||
|
automated: 'automated',
|
||||||
|
closedFlag: 'closedFlag',
|
||||||
|
notifyCompleteFlag: 'notifyCompleteFlag',
|
||||||
|
notificationSentFlat: 'notificationSentFlat',
|
||||||
|
opportunityId: 'opportunityId',
|
||||||
|
serviceTicketId: 'serviceTicketId',
|
||||||
|
contactId: 'contactId',
|
||||||
|
companyId: 'companyId',
|
||||||
|
activityTypeId: 'activityTypeId',
|
||||||
|
activityStatusId: 'activityStatusId',
|
||||||
|
createdById: 'createdById',
|
||||||
|
updatedById: 'updatedById',
|
||||||
|
closedById: 'closedById',
|
||||||
|
closedAt: 'closedAt',
|
||||||
|
createdAt: 'createdAt',
|
||||||
|
updatedAt: 'updatedAt'
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export type ActivityScalarFieldEnum = (typeof ActivityScalarFieldEnum)[keyof typeof ActivityScalarFieldEnum]
|
||||||
|
|
||||||
|
|
||||||
|
export const ActivityNotesScalarFieldEnum = {
|
||||||
|
id: 'id',
|
||||||
|
uid: 'uid',
|
||||||
|
notes: 'notes',
|
||||||
|
activityId: 'activityId',
|
||||||
|
internalAnalysisFlag: 'internalAnalysisFlag',
|
||||||
|
enteredById: 'enteredById',
|
||||||
|
updatedById: 'updatedById',
|
||||||
|
createdAt: 'createdAt',
|
||||||
|
updatedAt: 'updatedAt'
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export type ActivityNotesScalarFieldEnum = (typeof ActivityNotesScalarFieldEnum)[keyof typeof ActivityNotesScalarFieldEnum]
|
||||||
|
|
||||||
|
|
||||||
|
export const ActivityTypeScalarFieldEnum = {
|
||||||
|
id: 'id',
|
||||||
|
uid: 'uid',
|
||||||
|
name: 'name',
|
||||||
|
description: 'description',
|
||||||
|
inactiveFlag: 'inactiveFlag',
|
||||||
|
historyFlag: 'historyFlag',
|
||||||
|
defaultFlag: 'defaultFlag',
|
||||||
|
importFlag: 'importFlag',
|
||||||
|
emailFlag: 'emailFlag',
|
||||||
|
memoFlag: 'memoFlag',
|
||||||
|
pointsValue: 'pointsValue',
|
||||||
|
updatedById: 'updatedById',
|
||||||
|
createdById: 'createdById',
|
||||||
|
createdAt: 'createdAt',
|
||||||
|
updatedAt: 'updatedAt'
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export type ActivityTypeScalarFieldEnum = (typeof ActivityTypeScalarFieldEnum)[keyof typeof ActivityTypeScalarFieldEnum]
|
||||||
|
|
||||||
|
|
||||||
|
export const ActivityStatusScalarFieldEnum = {
|
||||||
|
id: 'id',
|
||||||
|
uid: 'uid',
|
||||||
|
name: 'name',
|
||||||
|
description: 'description',
|
||||||
|
closedFlag: 'closedFlag',
|
||||||
|
inactiveFlag: 'inactiveFlag',
|
||||||
|
defaultFlag: 'defaultFlag',
|
||||||
|
spawnFollowupFlag: 'spawnFollowupFlag',
|
||||||
|
updatedById: 'updatedById',
|
||||||
|
createdById: 'createdById',
|
||||||
|
createdAt: 'createdAt',
|
||||||
|
updatedAt: 'updatedAt'
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export type ActivityStatusScalarFieldEnum = (typeof ActivityStatusScalarFieldEnum)[keyof typeof ActivityStatusScalarFieldEnum]
|
||||||
|
|
||||||
|
|
||||||
|
export const TimeEntryScalarFieldEnum = {
|
||||||
|
id: 'id',
|
||||||
|
uid: 'uid',
|
||||||
|
memberId: 'memberId',
|
||||||
|
serviceTicketId: 'serviceTicketId',
|
||||||
|
activityId: 'activityId',
|
||||||
|
projectId: 'projectId',
|
||||||
|
chargeCodeId: 'chargeCodeId',
|
||||||
|
companyId: 'companyId',
|
||||||
|
statusId: 'statusId',
|
||||||
|
locationId: 'locationId',
|
||||||
|
contactId: 'contactId',
|
||||||
|
dateStart: 'dateStart',
|
||||||
|
timeStart: 'timeStart',
|
||||||
|
timeEnd: 'timeEnd',
|
||||||
|
notes: 'notes',
|
||||||
|
notesMd: 'notesMd',
|
||||||
|
internalNote: 'internalNote',
|
||||||
|
billableHours: 'billableHours',
|
||||||
|
actualHours: 'actualHours',
|
||||||
|
invoicedHours: 'invoicedHours',
|
||||||
|
deductedHours: 'deductedHours',
|
||||||
|
hourlyRate: 'hourlyRate',
|
||||||
|
effectiveRate: 'effectiveRate',
|
||||||
|
issueFlag: 'issueFlag',
|
||||||
|
mergedFlag: 'mergedFlag',
|
||||||
|
invoiceFlag: 'invoiceFlag',
|
||||||
|
billableFlag: 'billableFlag',
|
||||||
|
documentFlag: 'documentFlag',
|
||||||
|
teProblemFlag: 'teProblemFlag',
|
||||||
|
teResolutionFlag: 'teResolutionFlag',
|
||||||
|
teInternalAnalysisFlag: 'teInternalAnalysisFlag',
|
||||||
|
chargeToRecId: 'chargeToRecId',
|
||||||
|
chargeToType: 'chargeToType',
|
||||||
|
createdById: 'createdById',
|
||||||
|
updatedById: 'updatedById',
|
||||||
|
originalAuthorId: 'originalAuthorId',
|
||||||
|
createdAt: 'createdAt',
|
||||||
|
updatedAt: 'updatedAt'
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export type TimeEntryScalarFieldEnum = (typeof TimeEntryScalarFieldEnum)[keyof typeof TimeEntryScalarFieldEnum]
|
||||||
|
|
||||||
|
|
||||||
|
export const TimeEntryStatusScalarFieldEnum = {
|
||||||
|
id: 'id',
|
||||||
|
uid: 'uid',
|
||||||
|
statusId: 'statusId',
|
||||||
|
description: 'description',
|
||||||
|
action: 'action',
|
||||||
|
createdAt: 'createdAt',
|
||||||
|
updatedAt: 'updatedAt'
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export type TimeEntryStatusScalarFieldEnum = (typeof TimeEntryStatusScalarFieldEnum)[keyof typeof TimeEntryStatusScalarFieldEnum]
|
||||||
|
|
||||||
|
|
||||||
|
export const TimeEntryChargeCodeScalarFieldEnum = {
|
||||||
|
id: 'id',
|
||||||
|
uid: 'uid',
|
||||||
|
chargeCodeId: 'chargeCodeId',
|
||||||
|
description: 'description',
|
||||||
|
expenseFlag: 'expenseFlag',
|
||||||
|
timeFlag: 'timeFlag',
|
||||||
|
billableFlag: 'billableFlag',
|
||||||
|
invoiceFlag: 'invoiceFlag',
|
||||||
|
updatedById: 'updatedById',
|
||||||
|
createdById: 'createdById',
|
||||||
|
createdAt: 'createdAt',
|
||||||
|
updatedAt: 'updatedAt'
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export type TimeEntryChargeCodeScalarFieldEnum = (typeof TimeEntryChargeCodeScalarFieldEnum)[keyof typeof TimeEntryChargeCodeScalarFieldEnum]
|
||||||
|
|
||||||
|
|
||||||
|
export const TimeActivityClassScalarFieldEnum = {
|
||||||
|
id: 'id',
|
||||||
|
uid: 'uid',
|
||||||
|
description: 'description',
|
||||||
|
hourlyRate: 'hourlyRate',
|
||||||
|
inactiveFlag: 'inactiveFlag',
|
||||||
|
taxExemptFlag: 'taxExemptFlag',
|
||||||
|
createdById: 'createdById',
|
||||||
|
updatedById: 'updatedById',
|
||||||
|
createdAt: 'createdAt',
|
||||||
|
updatedAt: 'updatedAt'
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export type TimeActivityClassScalarFieldEnum = (typeof TimeActivityClassScalarFieldEnum)[keyof typeof TimeActivityClassScalarFieldEnum]
|
||||||
|
|
||||||
|
|
||||||
|
export const TimeActivityTypeScalarFieldEnum = {
|
||||||
|
id: 'id',
|
||||||
|
uid: 'uid',
|
||||||
|
description: 'description',
|
||||||
|
minHours: 'minHours',
|
||||||
|
maxHours: 'maxHours',
|
||||||
|
rate: 'rate',
|
||||||
|
costMultiplier: 'costMultiplier',
|
||||||
|
inactiveFlag: 'inactiveFlag',
|
||||||
|
invoiceFlag: 'invoiceFlag',
|
||||||
|
billableFlag: 'billableFlag',
|
||||||
|
utilizationFlag: 'utilizationFlag',
|
||||||
|
defaultFlag: 'defaultFlag',
|
||||||
|
multiplierFlag: 'multiplierFlag',
|
||||||
|
createdById: 'createdById',
|
||||||
|
updatedById: 'updatedById',
|
||||||
|
createdAt: 'createdAt',
|
||||||
|
updatedAt: 'updatedAt'
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export type TimeActivityTypeScalarFieldEnum = (typeof TimeActivityTypeScalarFieldEnum)[keyof typeof TimeActivityTypeScalarFieldEnum]
|
||||||
|
|
||||||
|
|
||||||
export const CredentialTypeScalarFieldEnum = {
|
export const CredentialTypeScalarFieldEnum = {
|
||||||
id: 'id',
|
id: 'id',
|
||||||
name: 'name',
|
name: 'name',
|
||||||
@@ -980,6 +1188,20 @@ export const CwMemberScalarFieldEnum = {
|
|||||||
export type CwMemberScalarFieldEnum = (typeof CwMemberScalarFieldEnum)[keyof typeof CwMemberScalarFieldEnum]
|
export type CwMemberScalarFieldEnum = (typeof CwMemberScalarFieldEnum)[keyof typeof CwMemberScalarFieldEnum]
|
||||||
|
|
||||||
|
|
||||||
|
export const CwMemberTypeScalarFieldEnum = {
|
||||||
|
id: 'id',
|
||||||
|
uid: 'uid',
|
||||||
|
description: 'description',
|
||||||
|
inactiveFlag: 'inactiveFlag',
|
||||||
|
updatedById: 'updatedById',
|
||||||
|
createdById: 'createdById',
|
||||||
|
createdAt: 'createdAt',
|
||||||
|
updatedAt: 'updatedAt'
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export type CwMemberTypeScalarFieldEnum = (typeof CwMemberTypeScalarFieldEnum)[keyof typeof CwMemberTypeScalarFieldEnum]
|
||||||
|
|
||||||
|
|
||||||
export const SortOrder = {
|
export const SortOrder = {
|
||||||
asc: 'asc',
|
asc: 'asc',
|
||||||
desc: 'desc'
|
desc: 'desc'
|
||||||
|
|||||||
@@ -47,10 +47,20 @@ export type * from './models/ScheduleStatus.ts'
|
|||||||
export type * from './models/ScheduleType.ts'
|
export type * from './models/ScheduleType.ts'
|
||||||
export type * from './models/ScheduleSpan.ts'
|
export type * from './models/ScheduleSpan.ts'
|
||||||
export type * from './models/Schedule.ts'
|
export type * from './models/Schedule.ts'
|
||||||
|
export type * from './models/Activity.ts'
|
||||||
|
export type * from './models/ActivityNotes.ts'
|
||||||
|
export type * from './models/ActivityType.ts'
|
||||||
|
export type * from './models/ActivityStatus.ts'
|
||||||
|
export type * from './models/TimeEntry.ts'
|
||||||
|
export type * from './models/TimeEntryStatus.ts'
|
||||||
|
export type * from './models/TimeEntryChargeCode.ts'
|
||||||
|
export type * from './models/TimeActivityClass.ts'
|
||||||
|
export type * from './models/TimeActivityType.ts'
|
||||||
export type * from './models/CredentialType.ts'
|
export type * from './models/CredentialType.ts'
|
||||||
export type * from './models/SecureValue.ts'
|
export type * from './models/SecureValue.ts'
|
||||||
export type * from './models/Credential.ts'
|
export type * from './models/Credential.ts'
|
||||||
export type * from './models/GeneratedQuotes.ts'
|
export type * from './models/GeneratedQuotes.ts'
|
||||||
export type * from './models/TaxCode.ts'
|
export type * from './models/TaxCode.ts'
|
||||||
export type * from './models/CwMember.ts'
|
export type * from './models/CwMember.ts'
|
||||||
|
export type * from './models/CwMemberType.ts'
|
||||||
export type * from './commonInputTypes.ts'
|
export type * from './commonInputTypes.ts'
|
||||||
@@ -293,6 +293,8 @@ export type CompanyWhereInput = {
|
|||||||
credentials?: Prisma.CredentialListRelationFilter
|
credentials?: Prisma.CredentialListRelationFilter
|
||||||
unifiSites?: Prisma.UnifiSiteListRelationFilter
|
unifiSites?: Prisma.UnifiSiteListRelationFilter
|
||||||
opportunities?: Prisma.OpportunityListRelationFilter
|
opportunities?: Prisma.OpportunityListRelationFilter
|
||||||
|
timeEntries?: Prisma.TimeEntryListRelationFilter
|
||||||
|
activities?: Prisma.ActivityListRelationFilter
|
||||||
deletedBy?: Prisma.XOR<Prisma.UserNullableScalarRelationFilter, Prisma.UserWhereInput> | null
|
deletedBy?: Prisma.XOR<Prisma.UserNullableScalarRelationFilter, Prisma.UserWhereInput> | null
|
||||||
enteredBy?: Prisma.XOR<Prisma.UserNullableScalarRelationFilter, Prisma.UserWhereInput> | null
|
enteredBy?: Prisma.XOR<Prisma.UserNullableScalarRelationFilter, Prisma.UserWhereInput> | null
|
||||||
serviceTickets?: Prisma.ServiceTicketListRelationFilter
|
serviceTickets?: Prisma.ServiceTicketListRelationFilter
|
||||||
@@ -319,6 +321,8 @@ export type CompanyOrderByWithRelationInput = {
|
|||||||
credentials?: Prisma.CredentialOrderByRelationAggregateInput
|
credentials?: Prisma.CredentialOrderByRelationAggregateInput
|
||||||
unifiSites?: Prisma.UnifiSiteOrderByRelationAggregateInput
|
unifiSites?: Prisma.UnifiSiteOrderByRelationAggregateInput
|
||||||
opportunities?: Prisma.OpportunityOrderByRelationAggregateInput
|
opportunities?: Prisma.OpportunityOrderByRelationAggregateInput
|
||||||
|
timeEntries?: Prisma.TimeEntryOrderByRelationAggregateInput
|
||||||
|
activities?: Prisma.ActivityOrderByRelationAggregateInput
|
||||||
deletedBy?: Prisma.UserOrderByWithRelationInput
|
deletedBy?: Prisma.UserOrderByWithRelationInput
|
||||||
enteredBy?: Prisma.UserOrderByWithRelationInput
|
enteredBy?: Prisma.UserOrderByWithRelationInput
|
||||||
serviceTickets?: Prisma.ServiceTicketOrderByRelationAggregateInput
|
serviceTickets?: Prisma.ServiceTicketOrderByRelationAggregateInput
|
||||||
@@ -348,6 +352,8 @@ export type CompanyWhereUniqueInput = Prisma.AtLeast<{
|
|||||||
credentials?: Prisma.CredentialListRelationFilter
|
credentials?: Prisma.CredentialListRelationFilter
|
||||||
unifiSites?: Prisma.UnifiSiteListRelationFilter
|
unifiSites?: Prisma.UnifiSiteListRelationFilter
|
||||||
opportunities?: Prisma.OpportunityListRelationFilter
|
opportunities?: Prisma.OpportunityListRelationFilter
|
||||||
|
timeEntries?: Prisma.TimeEntryListRelationFilter
|
||||||
|
activities?: Prisma.ActivityListRelationFilter
|
||||||
deletedBy?: Prisma.XOR<Prisma.UserNullableScalarRelationFilter, Prisma.UserWhereInput> | null
|
deletedBy?: Prisma.XOR<Prisma.UserNullableScalarRelationFilter, Prisma.UserWhereInput> | null
|
||||||
enteredBy?: Prisma.XOR<Prisma.UserNullableScalarRelationFilter, Prisma.UserWhereInput> | null
|
enteredBy?: Prisma.XOR<Prisma.UserNullableScalarRelationFilter, Prisma.UserWhereInput> | null
|
||||||
serviceTickets?: Prisma.ServiceTicketListRelationFilter
|
serviceTickets?: Prisma.ServiceTicketListRelationFilter
|
||||||
@@ -414,6 +420,8 @@ export type CompanyCreateInput = {
|
|||||||
credentials?: Prisma.CredentialCreateNestedManyWithoutCompanyInput
|
credentials?: Prisma.CredentialCreateNestedManyWithoutCompanyInput
|
||||||
unifiSites?: Prisma.UnifiSiteCreateNestedManyWithoutCompanyInput
|
unifiSites?: Prisma.UnifiSiteCreateNestedManyWithoutCompanyInput
|
||||||
opportunities?: Prisma.OpportunityCreateNestedManyWithoutCompanyInput
|
opportunities?: Prisma.OpportunityCreateNestedManyWithoutCompanyInput
|
||||||
|
timeEntries?: Prisma.TimeEntryCreateNestedManyWithoutCompanyInput
|
||||||
|
activities?: Prisma.ActivityCreateNestedManyWithoutCompanyInput
|
||||||
deletedBy?: Prisma.UserCreateNestedOneWithoutCompaniesDeletedInput
|
deletedBy?: Prisma.UserCreateNestedOneWithoutCompaniesDeletedInput
|
||||||
enteredBy?: Prisma.UserCreateNestedOneWithoutCompaniesEnteredInput
|
enteredBy?: Prisma.UserCreateNestedOneWithoutCompaniesEnteredInput
|
||||||
serviceTickets?: Prisma.ServiceTicketCreateNestedManyWithoutCompanyInput
|
serviceTickets?: Prisma.ServiceTicketCreateNestedManyWithoutCompanyInput
|
||||||
@@ -440,6 +448,8 @@ export type CompanyUncheckedCreateInput = {
|
|||||||
credentials?: Prisma.CredentialUncheckedCreateNestedManyWithoutCompanyInput
|
credentials?: Prisma.CredentialUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
unifiSites?: Prisma.UnifiSiteUncheckedCreateNestedManyWithoutCompanyInput
|
unifiSites?: Prisma.UnifiSiteUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
opportunities?: Prisma.OpportunityUncheckedCreateNestedManyWithoutCompanyInput
|
opportunities?: Prisma.OpportunityUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
|
timeEntries?: Prisma.TimeEntryUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
|
activities?: Prisma.ActivityUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
serviceTickets?: Prisma.ServiceTicketUncheckedCreateNestedManyWithoutCompanyInput
|
serviceTickets?: Prisma.ServiceTicketUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
billingServiceTickets?: Prisma.ServiceTicketUncheckedCreateNestedManyWithoutBillingCompanyInput
|
billingServiceTickets?: Prisma.ServiceTicketUncheckedCreateNestedManyWithoutBillingCompanyInput
|
||||||
}
|
}
|
||||||
@@ -462,6 +472,8 @@ export type CompanyUpdateInput = {
|
|||||||
credentials?: Prisma.CredentialUpdateManyWithoutCompanyNestedInput
|
credentials?: Prisma.CredentialUpdateManyWithoutCompanyNestedInput
|
||||||
unifiSites?: Prisma.UnifiSiteUpdateManyWithoutCompanyNestedInput
|
unifiSites?: Prisma.UnifiSiteUpdateManyWithoutCompanyNestedInput
|
||||||
opportunities?: Prisma.OpportunityUpdateManyWithoutCompanyNestedInput
|
opportunities?: Prisma.OpportunityUpdateManyWithoutCompanyNestedInput
|
||||||
|
timeEntries?: Prisma.TimeEntryUpdateManyWithoutCompanyNestedInput
|
||||||
|
activities?: Prisma.ActivityUpdateManyWithoutCompanyNestedInput
|
||||||
deletedBy?: Prisma.UserUpdateOneWithoutCompaniesDeletedNestedInput
|
deletedBy?: Prisma.UserUpdateOneWithoutCompaniesDeletedNestedInput
|
||||||
enteredBy?: Prisma.UserUpdateOneWithoutCompaniesEnteredNestedInput
|
enteredBy?: Prisma.UserUpdateOneWithoutCompaniesEnteredNestedInput
|
||||||
serviceTickets?: Prisma.ServiceTicketUpdateManyWithoutCompanyNestedInput
|
serviceTickets?: Prisma.ServiceTicketUpdateManyWithoutCompanyNestedInput
|
||||||
@@ -488,6 +500,8 @@ export type CompanyUncheckedUpdateInput = {
|
|||||||
credentials?: Prisma.CredentialUncheckedUpdateManyWithoutCompanyNestedInput
|
credentials?: Prisma.CredentialUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
unifiSites?: Prisma.UnifiSiteUncheckedUpdateManyWithoutCompanyNestedInput
|
unifiSites?: Prisma.UnifiSiteUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
opportunities?: Prisma.OpportunityUncheckedUpdateManyWithoutCompanyNestedInput
|
opportunities?: Prisma.OpportunityUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
|
timeEntries?: Prisma.TimeEntryUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
|
activities?: Prisma.ActivityUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
serviceTickets?: Prisma.ServiceTicketUncheckedUpdateManyWithoutCompanyNestedInput
|
serviceTickets?: Prisma.ServiceTicketUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
billingServiceTickets?: Prisma.ServiceTicketUncheckedUpdateManyWithoutBillingCompanyNestedInput
|
billingServiceTickets?: Prisma.ServiceTicketUncheckedUpdateManyWithoutBillingCompanyNestedInput
|
||||||
}
|
}
|
||||||
@@ -798,6 +812,36 @@ export type CompanyUpdateOneWithoutOpportunitiesNestedInput = {
|
|||||||
update?: Prisma.XOR<Prisma.XOR<Prisma.CompanyUpdateToOneWithWhereWithoutOpportunitiesInput, Prisma.CompanyUpdateWithoutOpportunitiesInput>, Prisma.CompanyUncheckedUpdateWithoutOpportunitiesInput>
|
update?: Prisma.XOR<Prisma.XOR<Prisma.CompanyUpdateToOneWithWhereWithoutOpportunitiesInput, Prisma.CompanyUpdateWithoutOpportunitiesInput>, Prisma.CompanyUncheckedUpdateWithoutOpportunitiesInput>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type CompanyCreateNestedOneWithoutActivitiesInput = {
|
||||||
|
create?: Prisma.XOR<Prisma.CompanyCreateWithoutActivitiesInput, Prisma.CompanyUncheckedCreateWithoutActivitiesInput>
|
||||||
|
connectOrCreate?: Prisma.CompanyCreateOrConnectWithoutActivitiesInput
|
||||||
|
connect?: Prisma.CompanyWhereUniqueInput
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CompanyUpdateOneWithoutActivitiesNestedInput = {
|
||||||
|
create?: Prisma.XOR<Prisma.CompanyCreateWithoutActivitiesInput, Prisma.CompanyUncheckedCreateWithoutActivitiesInput>
|
||||||
|
connectOrCreate?: Prisma.CompanyCreateOrConnectWithoutActivitiesInput
|
||||||
|
upsert?: Prisma.CompanyUpsertWithoutActivitiesInput
|
||||||
|
disconnect?: Prisma.CompanyWhereInput | boolean
|
||||||
|
delete?: Prisma.CompanyWhereInput | boolean
|
||||||
|
connect?: Prisma.CompanyWhereUniqueInput
|
||||||
|
update?: Prisma.XOR<Prisma.XOR<Prisma.CompanyUpdateToOneWithWhereWithoutActivitiesInput, Prisma.CompanyUpdateWithoutActivitiesInput>, Prisma.CompanyUncheckedUpdateWithoutActivitiesInput>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CompanyCreateNestedOneWithoutTimeEntriesInput = {
|
||||||
|
create?: Prisma.XOR<Prisma.CompanyCreateWithoutTimeEntriesInput, Prisma.CompanyUncheckedCreateWithoutTimeEntriesInput>
|
||||||
|
connectOrCreate?: Prisma.CompanyCreateOrConnectWithoutTimeEntriesInput
|
||||||
|
connect?: Prisma.CompanyWhereUniqueInput
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CompanyUpdateOneRequiredWithoutTimeEntriesNestedInput = {
|
||||||
|
create?: Prisma.XOR<Prisma.CompanyCreateWithoutTimeEntriesInput, Prisma.CompanyUncheckedCreateWithoutTimeEntriesInput>
|
||||||
|
connectOrCreate?: Prisma.CompanyCreateOrConnectWithoutTimeEntriesInput
|
||||||
|
upsert?: Prisma.CompanyUpsertWithoutTimeEntriesInput
|
||||||
|
connect?: Prisma.CompanyWhereUniqueInput
|
||||||
|
update?: Prisma.XOR<Prisma.XOR<Prisma.CompanyUpdateToOneWithWhereWithoutTimeEntriesInput, Prisma.CompanyUpdateWithoutTimeEntriesInput>, Prisma.CompanyUncheckedUpdateWithoutTimeEntriesInput>
|
||||||
|
}
|
||||||
|
|
||||||
export type CompanyCreateNestedOneWithoutCredentialsInput = {
|
export type CompanyCreateNestedOneWithoutCredentialsInput = {
|
||||||
create?: Prisma.XOR<Prisma.CompanyCreateWithoutCredentialsInput, Prisma.CompanyUncheckedCreateWithoutCredentialsInput>
|
create?: Prisma.XOR<Prisma.CompanyCreateWithoutCredentialsInput, Prisma.CompanyUncheckedCreateWithoutCredentialsInput>
|
||||||
connectOrCreate?: Prisma.CompanyCreateOrConnectWithoutCredentialsInput
|
connectOrCreate?: Prisma.CompanyCreateOrConnectWithoutCredentialsInput
|
||||||
@@ -830,6 +874,8 @@ export type CompanyCreateWithoutDeletedByInput = {
|
|||||||
credentials?: Prisma.CredentialCreateNestedManyWithoutCompanyInput
|
credentials?: Prisma.CredentialCreateNestedManyWithoutCompanyInput
|
||||||
unifiSites?: Prisma.UnifiSiteCreateNestedManyWithoutCompanyInput
|
unifiSites?: Prisma.UnifiSiteCreateNestedManyWithoutCompanyInput
|
||||||
opportunities?: Prisma.OpportunityCreateNestedManyWithoutCompanyInput
|
opportunities?: Prisma.OpportunityCreateNestedManyWithoutCompanyInput
|
||||||
|
timeEntries?: Prisma.TimeEntryCreateNestedManyWithoutCompanyInput
|
||||||
|
activities?: Prisma.ActivityCreateNestedManyWithoutCompanyInput
|
||||||
enteredBy?: Prisma.UserCreateNestedOneWithoutCompaniesEnteredInput
|
enteredBy?: Prisma.UserCreateNestedOneWithoutCompaniesEnteredInput
|
||||||
serviceTickets?: Prisma.ServiceTicketCreateNestedManyWithoutCompanyInput
|
serviceTickets?: Prisma.ServiceTicketCreateNestedManyWithoutCompanyInput
|
||||||
billingServiceTickets?: Prisma.ServiceTicketCreateNestedManyWithoutBillingCompanyInput
|
billingServiceTickets?: Prisma.ServiceTicketCreateNestedManyWithoutBillingCompanyInput
|
||||||
@@ -854,6 +900,8 @@ export type CompanyUncheckedCreateWithoutDeletedByInput = {
|
|||||||
credentials?: Prisma.CredentialUncheckedCreateNestedManyWithoutCompanyInput
|
credentials?: Prisma.CredentialUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
unifiSites?: Prisma.UnifiSiteUncheckedCreateNestedManyWithoutCompanyInput
|
unifiSites?: Prisma.UnifiSiteUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
opportunities?: Prisma.OpportunityUncheckedCreateNestedManyWithoutCompanyInput
|
opportunities?: Prisma.OpportunityUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
|
timeEntries?: Prisma.TimeEntryUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
|
activities?: Prisma.ActivityUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
serviceTickets?: Prisma.ServiceTicketUncheckedCreateNestedManyWithoutCompanyInput
|
serviceTickets?: Prisma.ServiceTicketUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
billingServiceTickets?: Prisma.ServiceTicketUncheckedCreateNestedManyWithoutBillingCompanyInput
|
billingServiceTickets?: Prisma.ServiceTicketUncheckedCreateNestedManyWithoutBillingCompanyInput
|
||||||
}
|
}
|
||||||
@@ -886,6 +934,8 @@ export type CompanyCreateWithoutEnteredByInput = {
|
|||||||
credentials?: Prisma.CredentialCreateNestedManyWithoutCompanyInput
|
credentials?: Prisma.CredentialCreateNestedManyWithoutCompanyInput
|
||||||
unifiSites?: Prisma.UnifiSiteCreateNestedManyWithoutCompanyInput
|
unifiSites?: Prisma.UnifiSiteCreateNestedManyWithoutCompanyInput
|
||||||
opportunities?: Prisma.OpportunityCreateNestedManyWithoutCompanyInput
|
opportunities?: Prisma.OpportunityCreateNestedManyWithoutCompanyInput
|
||||||
|
timeEntries?: Prisma.TimeEntryCreateNestedManyWithoutCompanyInput
|
||||||
|
activities?: Prisma.ActivityCreateNestedManyWithoutCompanyInput
|
||||||
deletedBy?: Prisma.UserCreateNestedOneWithoutCompaniesDeletedInput
|
deletedBy?: Prisma.UserCreateNestedOneWithoutCompaniesDeletedInput
|
||||||
serviceTickets?: Prisma.ServiceTicketCreateNestedManyWithoutCompanyInput
|
serviceTickets?: Prisma.ServiceTicketCreateNestedManyWithoutCompanyInput
|
||||||
billingServiceTickets?: Prisma.ServiceTicketCreateNestedManyWithoutBillingCompanyInput
|
billingServiceTickets?: Prisma.ServiceTicketCreateNestedManyWithoutBillingCompanyInput
|
||||||
@@ -910,6 +960,8 @@ export type CompanyUncheckedCreateWithoutEnteredByInput = {
|
|||||||
credentials?: Prisma.CredentialUncheckedCreateNestedManyWithoutCompanyInput
|
credentials?: Prisma.CredentialUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
unifiSites?: Prisma.UnifiSiteUncheckedCreateNestedManyWithoutCompanyInput
|
unifiSites?: Prisma.UnifiSiteUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
opportunities?: Prisma.OpportunityUncheckedCreateNestedManyWithoutCompanyInput
|
opportunities?: Prisma.OpportunityUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
|
timeEntries?: Prisma.TimeEntryUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
|
activities?: Prisma.ActivityUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
serviceTickets?: Prisma.ServiceTicketUncheckedCreateNestedManyWithoutCompanyInput
|
serviceTickets?: Prisma.ServiceTicketUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
billingServiceTickets?: Prisma.ServiceTicketUncheckedCreateNestedManyWithoutBillingCompanyInput
|
billingServiceTickets?: Prisma.ServiceTicketUncheckedCreateNestedManyWithoutBillingCompanyInput
|
||||||
}
|
}
|
||||||
@@ -993,6 +1045,8 @@ export type CompanyCreateWithoutUnifiSitesInput = {
|
|||||||
companyAddresses?: Prisma.CompanyAddressCreateNestedManyWithoutCompanyInput
|
companyAddresses?: Prisma.CompanyAddressCreateNestedManyWithoutCompanyInput
|
||||||
credentials?: Prisma.CredentialCreateNestedManyWithoutCompanyInput
|
credentials?: Prisma.CredentialCreateNestedManyWithoutCompanyInput
|
||||||
opportunities?: Prisma.OpportunityCreateNestedManyWithoutCompanyInput
|
opportunities?: Prisma.OpportunityCreateNestedManyWithoutCompanyInput
|
||||||
|
timeEntries?: Prisma.TimeEntryCreateNestedManyWithoutCompanyInput
|
||||||
|
activities?: Prisma.ActivityCreateNestedManyWithoutCompanyInput
|
||||||
deletedBy?: Prisma.UserCreateNestedOneWithoutCompaniesDeletedInput
|
deletedBy?: Prisma.UserCreateNestedOneWithoutCompaniesDeletedInput
|
||||||
enteredBy?: Prisma.UserCreateNestedOneWithoutCompaniesEnteredInput
|
enteredBy?: Prisma.UserCreateNestedOneWithoutCompaniesEnteredInput
|
||||||
serviceTickets?: Prisma.ServiceTicketCreateNestedManyWithoutCompanyInput
|
serviceTickets?: Prisma.ServiceTicketCreateNestedManyWithoutCompanyInput
|
||||||
@@ -1018,6 +1072,8 @@ export type CompanyUncheckedCreateWithoutUnifiSitesInput = {
|
|||||||
companyAddresses?: Prisma.CompanyAddressUncheckedCreateNestedManyWithoutCompanyInput
|
companyAddresses?: Prisma.CompanyAddressUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
credentials?: Prisma.CredentialUncheckedCreateNestedManyWithoutCompanyInput
|
credentials?: Prisma.CredentialUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
opportunities?: Prisma.OpportunityUncheckedCreateNestedManyWithoutCompanyInput
|
opportunities?: Prisma.OpportunityUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
|
timeEntries?: Prisma.TimeEntryUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
|
activities?: Prisma.ActivityUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
serviceTickets?: Prisma.ServiceTicketUncheckedCreateNestedManyWithoutCompanyInput
|
serviceTickets?: Prisma.ServiceTicketUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
billingServiceTickets?: Prisma.ServiceTicketUncheckedCreateNestedManyWithoutBillingCompanyInput
|
billingServiceTickets?: Prisma.ServiceTicketUncheckedCreateNestedManyWithoutBillingCompanyInput
|
||||||
}
|
}
|
||||||
@@ -1055,6 +1111,8 @@ export type CompanyUpdateWithoutUnifiSitesInput = {
|
|||||||
companyAddresses?: Prisma.CompanyAddressUpdateManyWithoutCompanyNestedInput
|
companyAddresses?: Prisma.CompanyAddressUpdateManyWithoutCompanyNestedInput
|
||||||
credentials?: Prisma.CredentialUpdateManyWithoutCompanyNestedInput
|
credentials?: Prisma.CredentialUpdateManyWithoutCompanyNestedInput
|
||||||
opportunities?: Prisma.OpportunityUpdateManyWithoutCompanyNestedInput
|
opportunities?: Prisma.OpportunityUpdateManyWithoutCompanyNestedInput
|
||||||
|
timeEntries?: Prisma.TimeEntryUpdateManyWithoutCompanyNestedInput
|
||||||
|
activities?: Prisma.ActivityUpdateManyWithoutCompanyNestedInput
|
||||||
deletedBy?: Prisma.UserUpdateOneWithoutCompaniesDeletedNestedInput
|
deletedBy?: Prisma.UserUpdateOneWithoutCompaniesDeletedNestedInput
|
||||||
enteredBy?: Prisma.UserUpdateOneWithoutCompaniesEnteredNestedInput
|
enteredBy?: Prisma.UserUpdateOneWithoutCompaniesEnteredNestedInput
|
||||||
serviceTickets?: Prisma.ServiceTicketUpdateManyWithoutCompanyNestedInput
|
serviceTickets?: Prisma.ServiceTicketUpdateManyWithoutCompanyNestedInput
|
||||||
@@ -1080,6 +1138,8 @@ export type CompanyUncheckedUpdateWithoutUnifiSitesInput = {
|
|||||||
companyAddresses?: Prisma.CompanyAddressUncheckedUpdateManyWithoutCompanyNestedInput
|
companyAddresses?: Prisma.CompanyAddressUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
credentials?: Prisma.CredentialUncheckedUpdateManyWithoutCompanyNestedInput
|
credentials?: Prisma.CredentialUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
opportunities?: Prisma.OpportunityUncheckedUpdateManyWithoutCompanyNestedInput
|
opportunities?: Prisma.OpportunityUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
|
timeEntries?: Prisma.TimeEntryUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
|
activities?: Prisma.ActivityUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
serviceTickets?: Prisma.ServiceTicketUncheckedUpdateManyWithoutCompanyNestedInput
|
serviceTickets?: Prisma.ServiceTicketUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
billingServiceTickets?: Prisma.ServiceTicketUncheckedUpdateManyWithoutBillingCompanyNestedInput
|
billingServiceTickets?: Prisma.ServiceTicketUncheckedUpdateManyWithoutBillingCompanyNestedInput
|
||||||
}
|
}
|
||||||
@@ -1101,6 +1161,8 @@ export type CompanyCreateWithoutCompanyAddressesInput = {
|
|||||||
credentials?: Prisma.CredentialCreateNestedManyWithoutCompanyInput
|
credentials?: Prisma.CredentialCreateNestedManyWithoutCompanyInput
|
||||||
unifiSites?: Prisma.UnifiSiteCreateNestedManyWithoutCompanyInput
|
unifiSites?: Prisma.UnifiSiteCreateNestedManyWithoutCompanyInput
|
||||||
opportunities?: Prisma.OpportunityCreateNestedManyWithoutCompanyInput
|
opportunities?: Prisma.OpportunityCreateNestedManyWithoutCompanyInput
|
||||||
|
timeEntries?: Prisma.TimeEntryCreateNestedManyWithoutCompanyInput
|
||||||
|
activities?: Prisma.ActivityCreateNestedManyWithoutCompanyInput
|
||||||
deletedBy?: Prisma.UserCreateNestedOneWithoutCompaniesDeletedInput
|
deletedBy?: Prisma.UserCreateNestedOneWithoutCompaniesDeletedInput
|
||||||
enteredBy?: Prisma.UserCreateNestedOneWithoutCompaniesEnteredInput
|
enteredBy?: Prisma.UserCreateNestedOneWithoutCompaniesEnteredInput
|
||||||
serviceTickets?: Prisma.ServiceTicketCreateNestedManyWithoutCompanyInput
|
serviceTickets?: Prisma.ServiceTicketCreateNestedManyWithoutCompanyInput
|
||||||
@@ -1126,6 +1188,8 @@ export type CompanyUncheckedCreateWithoutCompanyAddressesInput = {
|
|||||||
credentials?: Prisma.CredentialUncheckedCreateNestedManyWithoutCompanyInput
|
credentials?: Prisma.CredentialUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
unifiSites?: Prisma.UnifiSiteUncheckedCreateNestedManyWithoutCompanyInput
|
unifiSites?: Prisma.UnifiSiteUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
opportunities?: Prisma.OpportunityUncheckedCreateNestedManyWithoutCompanyInput
|
opportunities?: Prisma.OpportunityUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
|
timeEntries?: Prisma.TimeEntryUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
|
activities?: Prisma.ActivityUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
serviceTickets?: Prisma.ServiceTicketUncheckedCreateNestedManyWithoutCompanyInput
|
serviceTickets?: Prisma.ServiceTicketUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
billingServiceTickets?: Prisma.ServiceTicketUncheckedCreateNestedManyWithoutBillingCompanyInput
|
billingServiceTickets?: Prisma.ServiceTicketUncheckedCreateNestedManyWithoutBillingCompanyInput
|
||||||
}
|
}
|
||||||
@@ -1163,6 +1227,8 @@ export type CompanyUpdateWithoutCompanyAddressesInput = {
|
|||||||
credentials?: Prisma.CredentialUpdateManyWithoutCompanyNestedInput
|
credentials?: Prisma.CredentialUpdateManyWithoutCompanyNestedInput
|
||||||
unifiSites?: Prisma.UnifiSiteUpdateManyWithoutCompanyNestedInput
|
unifiSites?: Prisma.UnifiSiteUpdateManyWithoutCompanyNestedInput
|
||||||
opportunities?: Prisma.OpportunityUpdateManyWithoutCompanyNestedInput
|
opportunities?: Prisma.OpportunityUpdateManyWithoutCompanyNestedInput
|
||||||
|
timeEntries?: Prisma.TimeEntryUpdateManyWithoutCompanyNestedInput
|
||||||
|
activities?: Prisma.ActivityUpdateManyWithoutCompanyNestedInput
|
||||||
deletedBy?: Prisma.UserUpdateOneWithoutCompaniesDeletedNestedInput
|
deletedBy?: Prisma.UserUpdateOneWithoutCompaniesDeletedNestedInput
|
||||||
enteredBy?: Prisma.UserUpdateOneWithoutCompaniesEnteredNestedInput
|
enteredBy?: Prisma.UserUpdateOneWithoutCompaniesEnteredNestedInput
|
||||||
serviceTickets?: Prisma.ServiceTicketUpdateManyWithoutCompanyNestedInput
|
serviceTickets?: Prisma.ServiceTicketUpdateManyWithoutCompanyNestedInput
|
||||||
@@ -1188,6 +1254,8 @@ export type CompanyUncheckedUpdateWithoutCompanyAddressesInput = {
|
|||||||
credentials?: Prisma.CredentialUncheckedUpdateManyWithoutCompanyNestedInput
|
credentials?: Prisma.CredentialUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
unifiSites?: Prisma.UnifiSiteUncheckedUpdateManyWithoutCompanyNestedInput
|
unifiSites?: Prisma.UnifiSiteUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
opportunities?: Prisma.OpportunityUncheckedUpdateManyWithoutCompanyNestedInput
|
opportunities?: Prisma.OpportunityUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
|
timeEntries?: Prisma.TimeEntryUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
|
activities?: Prisma.ActivityUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
serviceTickets?: Prisma.ServiceTicketUncheckedUpdateManyWithoutCompanyNestedInput
|
serviceTickets?: Prisma.ServiceTicketUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
billingServiceTickets?: Prisma.ServiceTicketUncheckedUpdateManyWithoutBillingCompanyNestedInput
|
billingServiceTickets?: Prisma.ServiceTicketUncheckedUpdateManyWithoutBillingCompanyNestedInput
|
||||||
}
|
}
|
||||||
@@ -1209,6 +1277,8 @@ export type CompanyCreateWithoutContactsInput = {
|
|||||||
credentials?: Prisma.CredentialCreateNestedManyWithoutCompanyInput
|
credentials?: Prisma.CredentialCreateNestedManyWithoutCompanyInput
|
||||||
unifiSites?: Prisma.UnifiSiteCreateNestedManyWithoutCompanyInput
|
unifiSites?: Prisma.UnifiSiteCreateNestedManyWithoutCompanyInput
|
||||||
opportunities?: Prisma.OpportunityCreateNestedManyWithoutCompanyInput
|
opportunities?: Prisma.OpportunityCreateNestedManyWithoutCompanyInput
|
||||||
|
timeEntries?: Prisma.TimeEntryCreateNestedManyWithoutCompanyInput
|
||||||
|
activities?: Prisma.ActivityCreateNestedManyWithoutCompanyInput
|
||||||
deletedBy?: Prisma.UserCreateNestedOneWithoutCompaniesDeletedInput
|
deletedBy?: Prisma.UserCreateNestedOneWithoutCompaniesDeletedInput
|
||||||
enteredBy?: Prisma.UserCreateNestedOneWithoutCompaniesEnteredInput
|
enteredBy?: Prisma.UserCreateNestedOneWithoutCompaniesEnteredInput
|
||||||
serviceTickets?: Prisma.ServiceTicketCreateNestedManyWithoutCompanyInput
|
serviceTickets?: Prisma.ServiceTicketCreateNestedManyWithoutCompanyInput
|
||||||
@@ -1234,6 +1304,8 @@ export type CompanyUncheckedCreateWithoutContactsInput = {
|
|||||||
credentials?: Prisma.CredentialUncheckedCreateNestedManyWithoutCompanyInput
|
credentials?: Prisma.CredentialUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
unifiSites?: Prisma.UnifiSiteUncheckedCreateNestedManyWithoutCompanyInput
|
unifiSites?: Prisma.UnifiSiteUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
opportunities?: Prisma.OpportunityUncheckedCreateNestedManyWithoutCompanyInput
|
opportunities?: Prisma.OpportunityUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
|
timeEntries?: Prisma.TimeEntryUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
|
activities?: Prisma.ActivityUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
serviceTickets?: Prisma.ServiceTicketUncheckedCreateNestedManyWithoutCompanyInput
|
serviceTickets?: Prisma.ServiceTicketUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
billingServiceTickets?: Prisma.ServiceTicketUncheckedCreateNestedManyWithoutBillingCompanyInput
|
billingServiceTickets?: Prisma.ServiceTicketUncheckedCreateNestedManyWithoutBillingCompanyInput
|
||||||
}
|
}
|
||||||
@@ -1271,6 +1343,8 @@ export type CompanyUpdateWithoutContactsInput = {
|
|||||||
credentials?: Prisma.CredentialUpdateManyWithoutCompanyNestedInput
|
credentials?: Prisma.CredentialUpdateManyWithoutCompanyNestedInput
|
||||||
unifiSites?: Prisma.UnifiSiteUpdateManyWithoutCompanyNestedInput
|
unifiSites?: Prisma.UnifiSiteUpdateManyWithoutCompanyNestedInput
|
||||||
opportunities?: Prisma.OpportunityUpdateManyWithoutCompanyNestedInput
|
opportunities?: Prisma.OpportunityUpdateManyWithoutCompanyNestedInput
|
||||||
|
timeEntries?: Prisma.TimeEntryUpdateManyWithoutCompanyNestedInput
|
||||||
|
activities?: Prisma.ActivityUpdateManyWithoutCompanyNestedInput
|
||||||
deletedBy?: Prisma.UserUpdateOneWithoutCompaniesDeletedNestedInput
|
deletedBy?: Prisma.UserUpdateOneWithoutCompaniesDeletedNestedInput
|
||||||
enteredBy?: Prisma.UserUpdateOneWithoutCompaniesEnteredNestedInput
|
enteredBy?: Prisma.UserUpdateOneWithoutCompaniesEnteredNestedInput
|
||||||
serviceTickets?: Prisma.ServiceTicketUpdateManyWithoutCompanyNestedInput
|
serviceTickets?: Prisma.ServiceTicketUpdateManyWithoutCompanyNestedInput
|
||||||
@@ -1296,6 +1370,8 @@ export type CompanyUncheckedUpdateWithoutContactsInput = {
|
|||||||
credentials?: Prisma.CredentialUncheckedUpdateManyWithoutCompanyNestedInput
|
credentials?: Prisma.CredentialUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
unifiSites?: Prisma.UnifiSiteUncheckedUpdateManyWithoutCompanyNestedInput
|
unifiSites?: Prisma.UnifiSiteUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
opportunities?: Prisma.OpportunityUncheckedUpdateManyWithoutCompanyNestedInput
|
opportunities?: Prisma.OpportunityUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
|
timeEntries?: Prisma.TimeEntryUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
|
activities?: Prisma.ActivityUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
serviceTickets?: Prisma.ServiceTicketUncheckedUpdateManyWithoutCompanyNestedInput
|
serviceTickets?: Prisma.ServiceTicketUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
billingServiceTickets?: Prisma.ServiceTicketUncheckedUpdateManyWithoutBillingCompanyNestedInput
|
billingServiceTickets?: Prisma.ServiceTicketUncheckedUpdateManyWithoutBillingCompanyNestedInput
|
||||||
}
|
}
|
||||||
@@ -1318,6 +1394,8 @@ export type CompanyCreateWithoutServiceTicketsInput = {
|
|||||||
credentials?: Prisma.CredentialCreateNestedManyWithoutCompanyInput
|
credentials?: Prisma.CredentialCreateNestedManyWithoutCompanyInput
|
||||||
unifiSites?: Prisma.UnifiSiteCreateNestedManyWithoutCompanyInput
|
unifiSites?: Prisma.UnifiSiteCreateNestedManyWithoutCompanyInput
|
||||||
opportunities?: Prisma.OpportunityCreateNestedManyWithoutCompanyInput
|
opportunities?: Prisma.OpportunityCreateNestedManyWithoutCompanyInput
|
||||||
|
timeEntries?: Prisma.TimeEntryCreateNestedManyWithoutCompanyInput
|
||||||
|
activities?: Prisma.ActivityCreateNestedManyWithoutCompanyInput
|
||||||
deletedBy?: Prisma.UserCreateNestedOneWithoutCompaniesDeletedInput
|
deletedBy?: Prisma.UserCreateNestedOneWithoutCompaniesDeletedInput
|
||||||
enteredBy?: Prisma.UserCreateNestedOneWithoutCompaniesEnteredInput
|
enteredBy?: Prisma.UserCreateNestedOneWithoutCompaniesEnteredInput
|
||||||
billingServiceTickets?: Prisma.ServiceTicketCreateNestedManyWithoutBillingCompanyInput
|
billingServiceTickets?: Prisma.ServiceTicketCreateNestedManyWithoutBillingCompanyInput
|
||||||
@@ -1343,6 +1421,8 @@ export type CompanyUncheckedCreateWithoutServiceTicketsInput = {
|
|||||||
credentials?: Prisma.CredentialUncheckedCreateNestedManyWithoutCompanyInput
|
credentials?: Prisma.CredentialUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
unifiSites?: Prisma.UnifiSiteUncheckedCreateNestedManyWithoutCompanyInput
|
unifiSites?: Prisma.UnifiSiteUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
opportunities?: Prisma.OpportunityUncheckedCreateNestedManyWithoutCompanyInput
|
opportunities?: Prisma.OpportunityUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
|
timeEntries?: Prisma.TimeEntryUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
|
activities?: Prisma.ActivityUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
billingServiceTickets?: Prisma.ServiceTicketUncheckedCreateNestedManyWithoutBillingCompanyInput
|
billingServiceTickets?: Prisma.ServiceTicketUncheckedCreateNestedManyWithoutBillingCompanyInput
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1369,6 +1449,8 @@ export type CompanyCreateWithoutBillingServiceTicketsInput = {
|
|||||||
credentials?: Prisma.CredentialCreateNestedManyWithoutCompanyInput
|
credentials?: Prisma.CredentialCreateNestedManyWithoutCompanyInput
|
||||||
unifiSites?: Prisma.UnifiSiteCreateNestedManyWithoutCompanyInput
|
unifiSites?: Prisma.UnifiSiteCreateNestedManyWithoutCompanyInput
|
||||||
opportunities?: Prisma.OpportunityCreateNestedManyWithoutCompanyInput
|
opportunities?: Prisma.OpportunityCreateNestedManyWithoutCompanyInput
|
||||||
|
timeEntries?: Prisma.TimeEntryCreateNestedManyWithoutCompanyInput
|
||||||
|
activities?: Prisma.ActivityCreateNestedManyWithoutCompanyInput
|
||||||
deletedBy?: Prisma.UserCreateNestedOneWithoutCompaniesDeletedInput
|
deletedBy?: Prisma.UserCreateNestedOneWithoutCompaniesDeletedInput
|
||||||
enteredBy?: Prisma.UserCreateNestedOneWithoutCompaniesEnteredInput
|
enteredBy?: Prisma.UserCreateNestedOneWithoutCompaniesEnteredInput
|
||||||
serviceTickets?: Prisma.ServiceTicketCreateNestedManyWithoutCompanyInput
|
serviceTickets?: Prisma.ServiceTicketCreateNestedManyWithoutCompanyInput
|
||||||
@@ -1394,6 +1476,8 @@ export type CompanyUncheckedCreateWithoutBillingServiceTicketsInput = {
|
|||||||
credentials?: Prisma.CredentialUncheckedCreateNestedManyWithoutCompanyInput
|
credentials?: Prisma.CredentialUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
unifiSites?: Prisma.UnifiSiteUncheckedCreateNestedManyWithoutCompanyInput
|
unifiSites?: Prisma.UnifiSiteUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
opportunities?: Prisma.OpportunityUncheckedCreateNestedManyWithoutCompanyInput
|
opportunities?: Prisma.OpportunityUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
|
timeEntries?: Prisma.TimeEntryUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
|
activities?: Prisma.ActivityUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
serviceTickets?: Prisma.ServiceTicketUncheckedCreateNestedManyWithoutCompanyInput
|
serviceTickets?: Prisma.ServiceTicketUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1431,6 +1515,8 @@ export type CompanyUpdateWithoutServiceTicketsInput = {
|
|||||||
credentials?: Prisma.CredentialUpdateManyWithoutCompanyNestedInput
|
credentials?: Prisma.CredentialUpdateManyWithoutCompanyNestedInput
|
||||||
unifiSites?: Prisma.UnifiSiteUpdateManyWithoutCompanyNestedInput
|
unifiSites?: Prisma.UnifiSiteUpdateManyWithoutCompanyNestedInput
|
||||||
opportunities?: Prisma.OpportunityUpdateManyWithoutCompanyNestedInput
|
opportunities?: Prisma.OpportunityUpdateManyWithoutCompanyNestedInput
|
||||||
|
timeEntries?: Prisma.TimeEntryUpdateManyWithoutCompanyNestedInput
|
||||||
|
activities?: Prisma.ActivityUpdateManyWithoutCompanyNestedInput
|
||||||
deletedBy?: Prisma.UserUpdateOneWithoutCompaniesDeletedNestedInput
|
deletedBy?: Prisma.UserUpdateOneWithoutCompaniesDeletedNestedInput
|
||||||
enteredBy?: Prisma.UserUpdateOneWithoutCompaniesEnteredNestedInput
|
enteredBy?: Prisma.UserUpdateOneWithoutCompaniesEnteredNestedInput
|
||||||
billingServiceTickets?: Prisma.ServiceTicketUpdateManyWithoutBillingCompanyNestedInput
|
billingServiceTickets?: Prisma.ServiceTicketUpdateManyWithoutBillingCompanyNestedInput
|
||||||
@@ -1456,6 +1542,8 @@ export type CompanyUncheckedUpdateWithoutServiceTicketsInput = {
|
|||||||
credentials?: Prisma.CredentialUncheckedUpdateManyWithoutCompanyNestedInput
|
credentials?: Prisma.CredentialUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
unifiSites?: Prisma.UnifiSiteUncheckedUpdateManyWithoutCompanyNestedInput
|
unifiSites?: Prisma.UnifiSiteUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
opportunities?: Prisma.OpportunityUncheckedUpdateManyWithoutCompanyNestedInput
|
opportunities?: Prisma.OpportunityUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
|
timeEntries?: Prisma.TimeEntryUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
|
activities?: Prisma.ActivityUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
billingServiceTickets?: Prisma.ServiceTicketUncheckedUpdateManyWithoutBillingCompanyNestedInput
|
billingServiceTickets?: Prisma.ServiceTicketUncheckedUpdateManyWithoutBillingCompanyNestedInput
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1488,6 +1576,8 @@ export type CompanyUpdateWithoutBillingServiceTicketsInput = {
|
|||||||
credentials?: Prisma.CredentialUpdateManyWithoutCompanyNestedInput
|
credentials?: Prisma.CredentialUpdateManyWithoutCompanyNestedInput
|
||||||
unifiSites?: Prisma.UnifiSiteUpdateManyWithoutCompanyNestedInput
|
unifiSites?: Prisma.UnifiSiteUpdateManyWithoutCompanyNestedInput
|
||||||
opportunities?: Prisma.OpportunityUpdateManyWithoutCompanyNestedInput
|
opportunities?: Prisma.OpportunityUpdateManyWithoutCompanyNestedInput
|
||||||
|
timeEntries?: Prisma.TimeEntryUpdateManyWithoutCompanyNestedInput
|
||||||
|
activities?: Prisma.ActivityUpdateManyWithoutCompanyNestedInput
|
||||||
deletedBy?: Prisma.UserUpdateOneWithoutCompaniesDeletedNestedInput
|
deletedBy?: Prisma.UserUpdateOneWithoutCompaniesDeletedNestedInput
|
||||||
enteredBy?: Prisma.UserUpdateOneWithoutCompaniesEnteredNestedInput
|
enteredBy?: Prisma.UserUpdateOneWithoutCompaniesEnteredNestedInput
|
||||||
serviceTickets?: Prisma.ServiceTicketUpdateManyWithoutCompanyNestedInput
|
serviceTickets?: Prisma.ServiceTicketUpdateManyWithoutCompanyNestedInput
|
||||||
@@ -1513,6 +1603,8 @@ export type CompanyUncheckedUpdateWithoutBillingServiceTicketsInput = {
|
|||||||
credentials?: Prisma.CredentialUncheckedUpdateManyWithoutCompanyNestedInput
|
credentials?: Prisma.CredentialUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
unifiSites?: Prisma.UnifiSiteUncheckedUpdateManyWithoutCompanyNestedInput
|
unifiSites?: Prisma.UnifiSiteUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
opportunities?: Prisma.OpportunityUncheckedUpdateManyWithoutCompanyNestedInput
|
opportunities?: Prisma.OpportunityUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
|
timeEntries?: Prisma.TimeEntryUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
|
activities?: Prisma.ActivityUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
serviceTickets?: Prisma.ServiceTicketUncheckedUpdateManyWithoutCompanyNestedInput
|
serviceTickets?: Prisma.ServiceTicketUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1533,6 +1625,8 @@ export type CompanyCreateWithoutOpportunitiesInput = {
|
|||||||
companyAddresses?: Prisma.CompanyAddressCreateNestedManyWithoutCompanyInput
|
companyAddresses?: Prisma.CompanyAddressCreateNestedManyWithoutCompanyInput
|
||||||
credentials?: Prisma.CredentialCreateNestedManyWithoutCompanyInput
|
credentials?: Prisma.CredentialCreateNestedManyWithoutCompanyInput
|
||||||
unifiSites?: Prisma.UnifiSiteCreateNestedManyWithoutCompanyInput
|
unifiSites?: Prisma.UnifiSiteCreateNestedManyWithoutCompanyInput
|
||||||
|
timeEntries?: Prisma.TimeEntryCreateNestedManyWithoutCompanyInput
|
||||||
|
activities?: Prisma.ActivityCreateNestedManyWithoutCompanyInput
|
||||||
deletedBy?: Prisma.UserCreateNestedOneWithoutCompaniesDeletedInput
|
deletedBy?: Prisma.UserCreateNestedOneWithoutCompaniesDeletedInput
|
||||||
enteredBy?: Prisma.UserCreateNestedOneWithoutCompaniesEnteredInput
|
enteredBy?: Prisma.UserCreateNestedOneWithoutCompaniesEnteredInput
|
||||||
serviceTickets?: Prisma.ServiceTicketCreateNestedManyWithoutCompanyInput
|
serviceTickets?: Prisma.ServiceTicketCreateNestedManyWithoutCompanyInput
|
||||||
@@ -1558,6 +1652,8 @@ export type CompanyUncheckedCreateWithoutOpportunitiesInput = {
|
|||||||
companyAddresses?: Prisma.CompanyAddressUncheckedCreateNestedManyWithoutCompanyInput
|
companyAddresses?: Prisma.CompanyAddressUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
credentials?: Prisma.CredentialUncheckedCreateNestedManyWithoutCompanyInput
|
credentials?: Prisma.CredentialUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
unifiSites?: Prisma.UnifiSiteUncheckedCreateNestedManyWithoutCompanyInput
|
unifiSites?: Prisma.UnifiSiteUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
|
timeEntries?: Prisma.TimeEntryUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
|
activities?: Prisma.ActivityUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
serviceTickets?: Prisma.ServiceTicketUncheckedCreateNestedManyWithoutCompanyInput
|
serviceTickets?: Prisma.ServiceTicketUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
billingServiceTickets?: Prisma.ServiceTicketUncheckedCreateNestedManyWithoutBillingCompanyInput
|
billingServiceTickets?: Prisma.ServiceTicketUncheckedCreateNestedManyWithoutBillingCompanyInput
|
||||||
}
|
}
|
||||||
@@ -1595,6 +1691,8 @@ export type CompanyUpdateWithoutOpportunitiesInput = {
|
|||||||
companyAddresses?: Prisma.CompanyAddressUpdateManyWithoutCompanyNestedInput
|
companyAddresses?: Prisma.CompanyAddressUpdateManyWithoutCompanyNestedInput
|
||||||
credentials?: Prisma.CredentialUpdateManyWithoutCompanyNestedInput
|
credentials?: Prisma.CredentialUpdateManyWithoutCompanyNestedInput
|
||||||
unifiSites?: Prisma.UnifiSiteUpdateManyWithoutCompanyNestedInput
|
unifiSites?: Prisma.UnifiSiteUpdateManyWithoutCompanyNestedInput
|
||||||
|
timeEntries?: Prisma.TimeEntryUpdateManyWithoutCompanyNestedInput
|
||||||
|
activities?: Prisma.ActivityUpdateManyWithoutCompanyNestedInput
|
||||||
deletedBy?: Prisma.UserUpdateOneWithoutCompaniesDeletedNestedInput
|
deletedBy?: Prisma.UserUpdateOneWithoutCompaniesDeletedNestedInput
|
||||||
enteredBy?: Prisma.UserUpdateOneWithoutCompaniesEnteredNestedInput
|
enteredBy?: Prisma.UserUpdateOneWithoutCompaniesEnteredNestedInput
|
||||||
serviceTickets?: Prisma.ServiceTicketUpdateManyWithoutCompanyNestedInput
|
serviceTickets?: Prisma.ServiceTicketUpdateManyWithoutCompanyNestedInput
|
||||||
@@ -1620,6 +1718,240 @@ export type CompanyUncheckedUpdateWithoutOpportunitiesInput = {
|
|||||||
companyAddresses?: Prisma.CompanyAddressUncheckedUpdateManyWithoutCompanyNestedInput
|
companyAddresses?: Prisma.CompanyAddressUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
credentials?: Prisma.CredentialUncheckedUpdateManyWithoutCompanyNestedInput
|
credentials?: Prisma.CredentialUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
unifiSites?: Prisma.UnifiSiteUncheckedUpdateManyWithoutCompanyNestedInput
|
unifiSites?: Prisma.UnifiSiteUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
|
timeEntries?: Prisma.TimeEntryUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
|
activities?: Prisma.ActivityUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
|
serviceTickets?: Prisma.ServiceTicketUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
|
billingServiceTickets?: Prisma.ServiceTicketUncheckedUpdateManyWithoutBillingCompanyNestedInput
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CompanyCreateWithoutActivitiesInput = {
|
||||||
|
id: number
|
||||||
|
uid?: string
|
||||||
|
name: string
|
||||||
|
phone?: string | null
|
||||||
|
website?: string | null
|
||||||
|
deleteFlag?: boolean
|
||||||
|
dateDeleted?: Date | string | null
|
||||||
|
taxId?: string | null
|
||||||
|
taxExempt?: boolean
|
||||||
|
deletedAt?: Date | string | null
|
||||||
|
createdAt?: Date | string
|
||||||
|
updatedAt?: Date | string
|
||||||
|
contacts?: Prisma.ContactCreateNestedManyWithoutCompanyInput
|
||||||
|
companyAddresses?: Prisma.CompanyAddressCreateNestedManyWithoutCompanyInput
|
||||||
|
credentials?: Prisma.CredentialCreateNestedManyWithoutCompanyInput
|
||||||
|
unifiSites?: Prisma.UnifiSiteCreateNestedManyWithoutCompanyInput
|
||||||
|
opportunities?: Prisma.OpportunityCreateNestedManyWithoutCompanyInput
|
||||||
|
timeEntries?: Prisma.TimeEntryCreateNestedManyWithoutCompanyInput
|
||||||
|
deletedBy?: Prisma.UserCreateNestedOneWithoutCompaniesDeletedInput
|
||||||
|
enteredBy?: Prisma.UserCreateNestedOneWithoutCompaniesEnteredInput
|
||||||
|
serviceTickets?: Prisma.ServiceTicketCreateNestedManyWithoutCompanyInput
|
||||||
|
billingServiceTickets?: Prisma.ServiceTicketCreateNestedManyWithoutBillingCompanyInput
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CompanyUncheckedCreateWithoutActivitiesInput = {
|
||||||
|
id: number
|
||||||
|
uid?: string
|
||||||
|
name: string
|
||||||
|
phone?: string | null
|
||||||
|
website?: string | null
|
||||||
|
deleteFlag?: boolean
|
||||||
|
dateDeleted?: Date | string | null
|
||||||
|
taxId?: string | null
|
||||||
|
taxExempt?: boolean
|
||||||
|
enteredById?: string | null
|
||||||
|
deletedById?: string | null
|
||||||
|
deletedAt?: Date | string | null
|
||||||
|
createdAt?: Date | string
|
||||||
|
updatedAt?: Date | string
|
||||||
|
contacts?: Prisma.ContactUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
|
companyAddresses?: Prisma.CompanyAddressUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
|
credentials?: Prisma.CredentialUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
|
unifiSites?: Prisma.UnifiSiteUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
|
opportunities?: Prisma.OpportunityUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
|
timeEntries?: Prisma.TimeEntryUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
|
serviceTickets?: Prisma.ServiceTicketUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
|
billingServiceTickets?: Prisma.ServiceTicketUncheckedCreateNestedManyWithoutBillingCompanyInput
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CompanyCreateOrConnectWithoutActivitiesInput = {
|
||||||
|
where: Prisma.CompanyWhereUniqueInput
|
||||||
|
create: Prisma.XOR<Prisma.CompanyCreateWithoutActivitiesInput, Prisma.CompanyUncheckedCreateWithoutActivitiesInput>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CompanyUpsertWithoutActivitiesInput = {
|
||||||
|
update: Prisma.XOR<Prisma.CompanyUpdateWithoutActivitiesInput, Prisma.CompanyUncheckedUpdateWithoutActivitiesInput>
|
||||||
|
create: Prisma.XOR<Prisma.CompanyCreateWithoutActivitiesInput, Prisma.CompanyUncheckedCreateWithoutActivitiesInput>
|
||||||
|
where?: Prisma.CompanyWhereInput
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CompanyUpdateToOneWithWhereWithoutActivitiesInput = {
|
||||||
|
where?: Prisma.CompanyWhereInput
|
||||||
|
data: Prisma.XOR<Prisma.CompanyUpdateWithoutActivitiesInput, Prisma.CompanyUncheckedUpdateWithoutActivitiesInput>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CompanyUpdateWithoutActivitiesInput = {
|
||||||
|
id?: Prisma.IntFieldUpdateOperationsInput | number
|
||||||
|
uid?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
phone?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
website?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
deleteFlag?: Prisma.BoolFieldUpdateOperationsInput | boolean
|
||||||
|
dateDeleted?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
|
taxId?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
taxExempt?: Prisma.BoolFieldUpdateOperationsInput | boolean
|
||||||
|
deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
|
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
|
contacts?: Prisma.ContactUpdateManyWithoutCompanyNestedInput
|
||||||
|
companyAddresses?: Prisma.CompanyAddressUpdateManyWithoutCompanyNestedInput
|
||||||
|
credentials?: Prisma.CredentialUpdateManyWithoutCompanyNestedInput
|
||||||
|
unifiSites?: Prisma.UnifiSiteUpdateManyWithoutCompanyNestedInput
|
||||||
|
opportunities?: Prisma.OpportunityUpdateManyWithoutCompanyNestedInput
|
||||||
|
timeEntries?: Prisma.TimeEntryUpdateManyWithoutCompanyNestedInput
|
||||||
|
deletedBy?: Prisma.UserUpdateOneWithoutCompaniesDeletedNestedInput
|
||||||
|
enteredBy?: Prisma.UserUpdateOneWithoutCompaniesEnteredNestedInput
|
||||||
|
serviceTickets?: Prisma.ServiceTicketUpdateManyWithoutCompanyNestedInput
|
||||||
|
billingServiceTickets?: Prisma.ServiceTicketUpdateManyWithoutBillingCompanyNestedInput
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CompanyUncheckedUpdateWithoutActivitiesInput = {
|
||||||
|
id?: Prisma.IntFieldUpdateOperationsInput | number
|
||||||
|
uid?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
phone?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
website?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
deleteFlag?: Prisma.BoolFieldUpdateOperationsInput | boolean
|
||||||
|
dateDeleted?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
|
taxId?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
taxExempt?: Prisma.BoolFieldUpdateOperationsInput | boolean
|
||||||
|
enteredById?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
deletedById?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
|
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
|
contacts?: Prisma.ContactUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
|
companyAddresses?: Prisma.CompanyAddressUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
|
credentials?: Prisma.CredentialUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
|
unifiSites?: Prisma.UnifiSiteUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
|
opportunities?: Prisma.OpportunityUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
|
timeEntries?: Prisma.TimeEntryUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
|
serviceTickets?: Prisma.ServiceTicketUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
|
billingServiceTickets?: Prisma.ServiceTicketUncheckedUpdateManyWithoutBillingCompanyNestedInput
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CompanyCreateWithoutTimeEntriesInput = {
|
||||||
|
id: number
|
||||||
|
uid?: string
|
||||||
|
name: string
|
||||||
|
phone?: string | null
|
||||||
|
website?: string | null
|
||||||
|
deleteFlag?: boolean
|
||||||
|
dateDeleted?: Date | string | null
|
||||||
|
taxId?: string | null
|
||||||
|
taxExempt?: boolean
|
||||||
|
deletedAt?: Date | string | null
|
||||||
|
createdAt?: Date | string
|
||||||
|
updatedAt?: Date | string
|
||||||
|
contacts?: Prisma.ContactCreateNestedManyWithoutCompanyInput
|
||||||
|
companyAddresses?: Prisma.CompanyAddressCreateNestedManyWithoutCompanyInput
|
||||||
|
credentials?: Prisma.CredentialCreateNestedManyWithoutCompanyInput
|
||||||
|
unifiSites?: Prisma.UnifiSiteCreateNestedManyWithoutCompanyInput
|
||||||
|
opportunities?: Prisma.OpportunityCreateNestedManyWithoutCompanyInput
|
||||||
|
activities?: Prisma.ActivityCreateNestedManyWithoutCompanyInput
|
||||||
|
deletedBy?: Prisma.UserCreateNestedOneWithoutCompaniesDeletedInput
|
||||||
|
enteredBy?: Prisma.UserCreateNestedOneWithoutCompaniesEnteredInput
|
||||||
|
serviceTickets?: Prisma.ServiceTicketCreateNestedManyWithoutCompanyInput
|
||||||
|
billingServiceTickets?: Prisma.ServiceTicketCreateNestedManyWithoutBillingCompanyInput
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CompanyUncheckedCreateWithoutTimeEntriesInput = {
|
||||||
|
id: number
|
||||||
|
uid?: string
|
||||||
|
name: string
|
||||||
|
phone?: string | null
|
||||||
|
website?: string | null
|
||||||
|
deleteFlag?: boolean
|
||||||
|
dateDeleted?: Date | string | null
|
||||||
|
taxId?: string | null
|
||||||
|
taxExempt?: boolean
|
||||||
|
enteredById?: string | null
|
||||||
|
deletedById?: string | null
|
||||||
|
deletedAt?: Date | string | null
|
||||||
|
createdAt?: Date | string
|
||||||
|
updatedAt?: Date | string
|
||||||
|
contacts?: Prisma.ContactUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
|
companyAddresses?: Prisma.CompanyAddressUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
|
credentials?: Prisma.CredentialUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
|
unifiSites?: Prisma.UnifiSiteUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
|
opportunities?: Prisma.OpportunityUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
|
activities?: Prisma.ActivityUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
|
serviceTickets?: Prisma.ServiceTicketUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
|
billingServiceTickets?: Prisma.ServiceTicketUncheckedCreateNestedManyWithoutBillingCompanyInput
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CompanyCreateOrConnectWithoutTimeEntriesInput = {
|
||||||
|
where: Prisma.CompanyWhereUniqueInput
|
||||||
|
create: Prisma.XOR<Prisma.CompanyCreateWithoutTimeEntriesInput, Prisma.CompanyUncheckedCreateWithoutTimeEntriesInput>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CompanyUpsertWithoutTimeEntriesInput = {
|
||||||
|
update: Prisma.XOR<Prisma.CompanyUpdateWithoutTimeEntriesInput, Prisma.CompanyUncheckedUpdateWithoutTimeEntriesInput>
|
||||||
|
create: Prisma.XOR<Prisma.CompanyCreateWithoutTimeEntriesInput, Prisma.CompanyUncheckedCreateWithoutTimeEntriesInput>
|
||||||
|
where?: Prisma.CompanyWhereInput
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CompanyUpdateToOneWithWhereWithoutTimeEntriesInput = {
|
||||||
|
where?: Prisma.CompanyWhereInput
|
||||||
|
data: Prisma.XOR<Prisma.CompanyUpdateWithoutTimeEntriesInput, Prisma.CompanyUncheckedUpdateWithoutTimeEntriesInput>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CompanyUpdateWithoutTimeEntriesInput = {
|
||||||
|
id?: Prisma.IntFieldUpdateOperationsInput | number
|
||||||
|
uid?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
phone?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
website?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
deleteFlag?: Prisma.BoolFieldUpdateOperationsInput | boolean
|
||||||
|
dateDeleted?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
|
taxId?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
taxExempt?: Prisma.BoolFieldUpdateOperationsInput | boolean
|
||||||
|
deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
|
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
|
contacts?: Prisma.ContactUpdateManyWithoutCompanyNestedInput
|
||||||
|
companyAddresses?: Prisma.CompanyAddressUpdateManyWithoutCompanyNestedInput
|
||||||
|
credentials?: Prisma.CredentialUpdateManyWithoutCompanyNestedInput
|
||||||
|
unifiSites?: Prisma.UnifiSiteUpdateManyWithoutCompanyNestedInput
|
||||||
|
opportunities?: Prisma.OpportunityUpdateManyWithoutCompanyNestedInput
|
||||||
|
activities?: Prisma.ActivityUpdateManyWithoutCompanyNestedInput
|
||||||
|
deletedBy?: Prisma.UserUpdateOneWithoutCompaniesDeletedNestedInput
|
||||||
|
enteredBy?: Prisma.UserUpdateOneWithoutCompaniesEnteredNestedInput
|
||||||
|
serviceTickets?: Prisma.ServiceTicketUpdateManyWithoutCompanyNestedInput
|
||||||
|
billingServiceTickets?: Prisma.ServiceTicketUpdateManyWithoutBillingCompanyNestedInput
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CompanyUncheckedUpdateWithoutTimeEntriesInput = {
|
||||||
|
id?: Prisma.IntFieldUpdateOperationsInput | number
|
||||||
|
uid?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
phone?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
website?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
deleteFlag?: Prisma.BoolFieldUpdateOperationsInput | boolean
|
||||||
|
dateDeleted?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
|
taxId?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
taxExempt?: Prisma.BoolFieldUpdateOperationsInput | boolean
|
||||||
|
enteredById?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
deletedById?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
|
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
|
contacts?: Prisma.ContactUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
|
companyAddresses?: Prisma.CompanyAddressUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
|
credentials?: Prisma.CredentialUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
|
unifiSites?: Prisma.UnifiSiteUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
|
opportunities?: Prisma.OpportunityUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
|
activities?: Prisma.ActivityUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
serviceTickets?: Prisma.ServiceTicketUncheckedUpdateManyWithoutCompanyNestedInput
|
serviceTickets?: Prisma.ServiceTicketUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
billingServiceTickets?: Prisma.ServiceTicketUncheckedUpdateManyWithoutBillingCompanyNestedInput
|
billingServiceTickets?: Prisma.ServiceTicketUncheckedUpdateManyWithoutBillingCompanyNestedInput
|
||||||
}
|
}
|
||||||
@@ -1641,6 +1973,8 @@ export type CompanyCreateWithoutCredentialsInput = {
|
|||||||
companyAddresses?: Prisma.CompanyAddressCreateNestedManyWithoutCompanyInput
|
companyAddresses?: Prisma.CompanyAddressCreateNestedManyWithoutCompanyInput
|
||||||
unifiSites?: Prisma.UnifiSiteCreateNestedManyWithoutCompanyInput
|
unifiSites?: Prisma.UnifiSiteCreateNestedManyWithoutCompanyInput
|
||||||
opportunities?: Prisma.OpportunityCreateNestedManyWithoutCompanyInput
|
opportunities?: Prisma.OpportunityCreateNestedManyWithoutCompanyInput
|
||||||
|
timeEntries?: Prisma.TimeEntryCreateNestedManyWithoutCompanyInput
|
||||||
|
activities?: Prisma.ActivityCreateNestedManyWithoutCompanyInput
|
||||||
deletedBy?: Prisma.UserCreateNestedOneWithoutCompaniesDeletedInput
|
deletedBy?: Prisma.UserCreateNestedOneWithoutCompaniesDeletedInput
|
||||||
enteredBy?: Prisma.UserCreateNestedOneWithoutCompaniesEnteredInput
|
enteredBy?: Prisma.UserCreateNestedOneWithoutCompaniesEnteredInput
|
||||||
serviceTickets?: Prisma.ServiceTicketCreateNestedManyWithoutCompanyInput
|
serviceTickets?: Prisma.ServiceTicketCreateNestedManyWithoutCompanyInput
|
||||||
@@ -1666,6 +2000,8 @@ export type CompanyUncheckedCreateWithoutCredentialsInput = {
|
|||||||
companyAddresses?: Prisma.CompanyAddressUncheckedCreateNestedManyWithoutCompanyInput
|
companyAddresses?: Prisma.CompanyAddressUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
unifiSites?: Prisma.UnifiSiteUncheckedCreateNestedManyWithoutCompanyInput
|
unifiSites?: Prisma.UnifiSiteUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
opportunities?: Prisma.OpportunityUncheckedCreateNestedManyWithoutCompanyInput
|
opportunities?: Prisma.OpportunityUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
|
timeEntries?: Prisma.TimeEntryUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
|
activities?: Prisma.ActivityUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
serviceTickets?: Prisma.ServiceTicketUncheckedCreateNestedManyWithoutCompanyInput
|
serviceTickets?: Prisma.ServiceTicketUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
billingServiceTickets?: Prisma.ServiceTicketUncheckedCreateNestedManyWithoutBillingCompanyInput
|
billingServiceTickets?: Prisma.ServiceTicketUncheckedCreateNestedManyWithoutBillingCompanyInput
|
||||||
}
|
}
|
||||||
@@ -1703,6 +2039,8 @@ export type CompanyUpdateWithoutCredentialsInput = {
|
|||||||
companyAddresses?: Prisma.CompanyAddressUpdateManyWithoutCompanyNestedInput
|
companyAddresses?: Prisma.CompanyAddressUpdateManyWithoutCompanyNestedInput
|
||||||
unifiSites?: Prisma.UnifiSiteUpdateManyWithoutCompanyNestedInput
|
unifiSites?: Prisma.UnifiSiteUpdateManyWithoutCompanyNestedInput
|
||||||
opportunities?: Prisma.OpportunityUpdateManyWithoutCompanyNestedInput
|
opportunities?: Prisma.OpportunityUpdateManyWithoutCompanyNestedInput
|
||||||
|
timeEntries?: Prisma.TimeEntryUpdateManyWithoutCompanyNestedInput
|
||||||
|
activities?: Prisma.ActivityUpdateManyWithoutCompanyNestedInput
|
||||||
deletedBy?: Prisma.UserUpdateOneWithoutCompaniesDeletedNestedInput
|
deletedBy?: Prisma.UserUpdateOneWithoutCompaniesDeletedNestedInput
|
||||||
enteredBy?: Prisma.UserUpdateOneWithoutCompaniesEnteredNestedInput
|
enteredBy?: Prisma.UserUpdateOneWithoutCompaniesEnteredNestedInput
|
||||||
serviceTickets?: Prisma.ServiceTicketUpdateManyWithoutCompanyNestedInput
|
serviceTickets?: Prisma.ServiceTicketUpdateManyWithoutCompanyNestedInput
|
||||||
@@ -1728,6 +2066,8 @@ export type CompanyUncheckedUpdateWithoutCredentialsInput = {
|
|||||||
companyAddresses?: Prisma.CompanyAddressUncheckedUpdateManyWithoutCompanyNestedInput
|
companyAddresses?: Prisma.CompanyAddressUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
unifiSites?: Prisma.UnifiSiteUncheckedUpdateManyWithoutCompanyNestedInput
|
unifiSites?: Prisma.UnifiSiteUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
opportunities?: Prisma.OpportunityUncheckedUpdateManyWithoutCompanyNestedInput
|
opportunities?: Prisma.OpportunityUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
|
timeEntries?: Prisma.TimeEntryUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
|
activities?: Prisma.ActivityUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
serviceTickets?: Prisma.ServiceTicketUncheckedUpdateManyWithoutCompanyNestedInput
|
serviceTickets?: Prisma.ServiceTicketUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
billingServiceTickets?: Prisma.ServiceTicketUncheckedUpdateManyWithoutBillingCompanyNestedInput
|
billingServiceTickets?: Prisma.ServiceTicketUncheckedUpdateManyWithoutBillingCompanyNestedInput
|
||||||
}
|
}
|
||||||
@@ -1782,6 +2122,8 @@ export type CompanyUpdateWithoutDeletedByInput = {
|
|||||||
credentials?: Prisma.CredentialUpdateManyWithoutCompanyNestedInput
|
credentials?: Prisma.CredentialUpdateManyWithoutCompanyNestedInput
|
||||||
unifiSites?: Prisma.UnifiSiteUpdateManyWithoutCompanyNestedInput
|
unifiSites?: Prisma.UnifiSiteUpdateManyWithoutCompanyNestedInput
|
||||||
opportunities?: Prisma.OpportunityUpdateManyWithoutCompanyNestedInput
|
opportunities?: Prisma.OpportunityUpdateManyWithoutCompanyNestedInput
|
||||||
|
timeEntries?: Prisma.TimeEntryUpdateManyWithoutCompanyNestedInput
|
||||||
|
activities?: Prisma.ActivityUpdateManyWithoutCompanyNestedInput
|
||||||
enteredBy?: Prisma.UserUpdateOneWithoutCompaniesEnteredNestedInput
|
enteredBy?: Prisma.UserUpdateOneWithoutCompaniesEnteredNestedInput
|
||||||
serviceTickets?: Prisma.ServiceTicketUpdateManyWithoutCompanyNestedInput
|
serviceTickets?: Prisma.ServiceTicketUpdateManyWithoutCompanyNestedInput
|
||||||
billingServiceTickets?: Prisma.ServiceTicketUpdateManyWithoutBillingCompanyNestedInput
|
billingServiceTickets?: Prisma.ServiceTicketUpdateManyWithoutBillingCompanyNestedInput
|
||||||
@@ -1806,6 +2148,8 @@ export type CompanyUncheckedUpdateWithoutDeletedByInput = {
|
|||||||
credentials?: Prisma.CredentialUncheckedUpdateManyWithoutCompanyNestedInput
|
credentials?: Prisma.CredentialUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
unifiSites?: Prisma.UnifiSiteUncheckedUpdateManyWithoutCompanyNestedInput
|
unifiSites?: Prisma.UnifiSiteUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
opportunities?: Prisma.OpportunityUncheckedUpdateManyWithoutCompanyNestedInput
|
opportunities?: Prisma.OpportunityUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
|
timeEntries?: Prisma.TimeEntryUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
|
activities?: Prisma.ActivityUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
serviceTickets?: Prisma.ServiceTicketUncheckedUpdateManyWithoutCompanyNestedInput
|
serviceTickets?: Prisma.ServiceTicketUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
billingServiceTickets?: Prisma.ServiceTicketUncheckedUpdateManyWithoutBillingCompanyNestedInput
|
billingServiceTickets?: Prisma.ServiceTicketUncheckedUpdateManyWithoutBillingCompanyNestedInput
|
||||||
}
|
}
|
||||||
@@ -1844,6 +2188,8 @@ export type CompanyUpdateWithoutEnteredByInput = {
|
|||||||
credentials?: Prisma.CredentialUpdateManyWithoutCompanyNestedInput
|
credentials?: Prisma.CredentialUpdateManyWithoutCompanyNestedInput
|
||||||
unifiSites?: Prisma.UnifiSiteUpdateManyWithoutCompanyNestedInput
|
unifiSites?: Prisma.UnifiSiteUpdateManyWithoutCompanyNestedInput
|
||||||
opportunities?: Prisma.OpportunityUpdateManyWithoutCompanyNestedInput
|
opportunities?: Prisma.OpportunityUpdateManyWithoutCompanyNestedInput
|
||||||
|
timeEntries?: Prisma.TimeEntryUpdateManyWithoutCompanyNestedInput
|
||||||
|
activities?: Prisma.ActivityUpdateManyWithoutCompanyNestedInput
|
||||||
deletedBy?: Prisma.UserUpdateOneWithoutCompaniesDeletedNestedInput
|
deletedBy?: Prisma.UserUpdateOneWithoutCompaniesDeletedNestedInput
|
||||||
serviceTickets?: Prisma.ServiceTicketUpdateManyWithoutCompanyNestedInput
|
serviceTickets?: Prisma.ServiceTicketUpdateManyWithoutCompanyNestedInput
|
||||||
billingServiceTickets?: Prisma.ServiceTicketUpdateManyWithoutBillingCompanyNestedInput
|
billingServiceTickets?: Prisma.ServiceTicketUpdateManyWithoutBillingCompanyNestedInput
|
||||||
@@ -1868,6 +2214,8 @@ export type CompanyUncheckedUpdateWithoutEnteredByInput = {
|
|||||||
credentials?: Prisma.CredentialUncheckedUpdateManyWithoutCompanyNestedInput
|
credentials?: Prisma.CredentialUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
unifiSites?: Prisma.UnifiSiteUncheckedUpdateManyWithoutCompanyNestedInput
|
unifiSites?: Prisma.UnifiSiteUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
opportunities?: Prisma.OpportunityUncheckedUpdateManyWithoutCompanyNestedInput
|
opportunities?: Prisma.OpportunityUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
|
timeEntries?: Prisma.TimeEntryUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
|
activities?: Prisma.ActivityUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
serviceTickets?: Prisma.ServiceTicketUncheckedUpdateManyWithoutCompanyNestedInput
|
serviceTickets?: Prisma.ServiceTicketUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
billingServiceTickets?: Prisma.ServiceTicketUncheckedUpdateManyWithoutBillingCompanyNestedInput
|
billingServiceTickets?: Prisma.ServiceTicketUncheckedUpdateManyWithoutBillingCompanyNestedInput
|
||||||
}
|
}
|
||||||
@@ -1899,6 +2247,8 @@ export type CompanyCountOutputType = {
|
|||||||
credentials: number
|
credentials: number
|
||||||
unifiSites: number
|
unifiSites: number
|
||||||
opportunities: number
|
opportunities: number
|
||||||
|
timeEntries: number
|
||||||
|
activities: number
|
||||||
serviceTickets: number
|
serviceTickets: number
|
||||||
billingServiceTickets: number
|
billingServiceTickets: number
|
||||||
}
|
}
|
||||||
@@ -1909,6 +2259,8 @@ export type CompanyCountOutputTypeSelect<ExtArgs extends runtime.Types.Extension
|
|||||||
credentials?: boolean | CompanyCountOutputTypeCountCredentialsArgs
|
credentials?: boolean | CompanyCountOutputTypeCountCredentialsArgs
|
||||||
unifiSites?: boolean | CompanyCountOutputTypeCountUnifiSitesArgs
|
unifiSites?: boolean | CompanyCountOutputTypeCountUnifiSitesArgs
|
||||||
opportunities?: boolean | CompanyCountOutputTypeCountOpportunitiesArgs
|
opportunities?: boolean | CompanyCountOutputTypeCountOpportunitiesArgs
|
||||||
|
timeEntries?: boolean | CompanyCountOutputTypeCountTimeEntriesArgs
|
||||||
|
activities?: boolean | CompanyCountOutputTypeCountActivitiesArgs
|
||||||
serviceTickets?: boolean | CompanyCountOutputTypeCountServiceTicketsArgs
|
serviceTickets?: boolean | CompanyCountOutputTypeCountServiceTicketsArgs
|
||||||
billingServiceTickets?: boolean | CompanyCountOutputTypeCountBillingServiceTicketsArgs
|
billingServiceTickets?: boolean | CompanyCountOutputTypeCountBillingServiceTicketsArgs
|
||||||
}
|
}
|
||||||
@@ -1958,6 +2310,20 @@ export type CompanyCountOutputTypeCountOpportunitiesArgs<ExtArgs extends runtime
|
|||||||
where?: Prisma.OpportunityWhereInput
|
where?: Prisma.OpportunityWhereInput
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CompanyCountOutputType without action
|
||||||
|
*/
|
||||||
|
export type CompanyCountOutputTypeCountTimeEntriesArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||||
|
where?: Prisma.TimeEntryWhereInput
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CompanyCountOutputType without action
|
||||||
|
*/
|
||||||
|
export type CompanyCountOutputTypeCountActivitiesArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||||
|
where?: Prisma.ActivityWhereInput
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CompanyCountOutputType without action
|
* CompanyCountOutputType without action
|
||||||
*/
|
*/
|
||||||
@@ -1993,6 +2359,8 @@ export type CompanySelect<ExtArgs extends runtime.Types.Extensions.InternalArgs
|
|||||||
credentials?: boolean | Prisma.Company$credentialsArgs<ExtArgs>
|
credentials?: boolean | Prisma.Company$credentialsArgs<ExtArgs>
|
||||||
unifiSites?: boolean | Prisma.Company$unifiSitesArgs<ExtArgs>
|
unifiSites?: boolean | Prisma.Company$unifiSitesArgs<ExtArgs>
|
||||||
opportunities?: boolean | Prisma.Company$opportunitiesArgs<ExtArgs>
|
opportunities?: boolean | Prisma.Company$opportunitiesArgs<ExtArgs>
|
||||||
|
timeEntries?: boolean | Prisma.Company$timeEntriesArgs<ExtArgs>
|
||||||
|
activities?: boolean | Prisma.Company$activitiesArgs<ExtArgs>
|
||||||
deletedBy?: boolean | Prisma.Company$deletedByArgs<ExtArgs>
|
deletedBy?: boolean | Prisma.Company$deletedByArgs<ExtArgs>
|
||||||
enteredBy?: boolean | Prisma.Company$enteredByArgs<ExtArgs>
|
enteredBy?: boolean | Prisma.Company$enteredByArgs<ExtArgs>
|
||||||
serviceTickets?: boolean | Prisma.Company$serviceTicketsArgs<ExtArgs>
|
serviceTickets?: boolean | Prisma.Company$serviceTicketsArgs<ExtArgs>
|
||||||
@@ -2062,6 +2430,8 @@ export type CompanyInclude<ExtArgs extends runtime.Types.Extensions.InternalArgs
|
|||||||
credentials?: boolean | Prisma.Company$credentialsArgs<ExtArgs>
|
credentials?: boolean | Prisma.Company$credentialsArgs<ExtArgs>
|
||||||
unifiSites?: boolean | Prisma.Company$unifiSitesArgs<ExtArgs>
|
unifiSites?: boolean | Prisma.Company$unifiSitesArgs<ExtArgs>
|
||||||
opportunities?: boolean | Prisma.Company$opportunitiesArgs<ExtArgs>
|
opportunities?: boolean | Prisma.Company$opportunitiesArgs<ExtArgs>
|
||||||
|
timeEntries?: boolean | Prisma.Company$timeEntriesArgs<ExtArgs>
|
||||||
|
activities?: boolean | Prisma.Company$activitiesArgs<ExtArgs>
|
||||||
deletedBy?: boolean | Prisma.Company$deletedByArgs<ExtArgs>
|
deletedBy?: boolean | Prisma.Company$deletedByArgs<ExtArgs>
|
||||||
enteredBy?: boolean | Prisma.Company$enteredByArgs<ExtArgs>
|
enteredBy?: boolean | Prisma.Company$enteredByArgs<ExtArgs>
|
||||||
serviceTickets?: boolean | Prisma.Company$serviceTicketsArgs<ExtArgs>
|
serviceTickets?: boolean | Prisma.Company$serviceTicketsArgs<ExtArgs>
|
||||||
@@ -2085,6 +2455,8 @@ export type $CompanyPayload<ExtArgs extends runtime.Types.Extensions.InternalArg
|
|||||||
credentials: Prisma.$CredentialPayload<ExtArgs>[]
|
credentials: Prisma.$CredentialPayload<ExtArgs>[]
|
||||||
unifiSites: Prisma.$UnifiSitePayload<ExtArgs>[]
|
unifiSites: Prisma.$UnifiSitePayload<ExtArgs>[]
|
||||||
opportunities: Prisma.$OpportunityPayload<ExtArgs>[]
|
opportunities: Prisma.$OpportunityPayload<ExtArgs>[]
|
||||||
|
timeEntries: Prisma.$TimeEntryPayload<ExtArgs>[]
|
||||||
|
activities: Prisma.$ActivityPayload<ExtArgs>[]
|
||||||
deletedBy: Prisma.$UserPayload<ExtArgs> | null
|
deletedBy: Prisma.$UserPayload<ExtArgs> | null
|
||||||
enteredBy: Prisma.$UserPayload<ExtArgs> | null
|
enteredBy: Prisma.$UserPayload<ExtArgs> | null
|
||||||
serviceTickets: Prisma.$ServiceTicketPayload<ExtArgs>[]
|
serviceTickets: Prisma.$ServiceTicketPayload<ExtArgs>[]
|
||||||
@@ -2504,6 +2876,8 @@ export interface Prisma__CompanyClient<T, Null = never, ExtArgs extends runtime.
|
|||||||
credentials<T extends Prisma.Company$credentialsArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.Company$credentialsArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$CredentialPayload<ExtArgs>, T, "findMany", GlobalOmitOptions> | Null>
|
credentials<T extends Prisma.Company$credentialsArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.Company$credentialsArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$CredentialPayload<ExtArgs>, T, "findMany", GlobalOmitOptions> | Null>
|
||||||
unifiSites<T extends Prisma.Company$unifiSitesArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.Company$unifiSitesArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$UnifiSitePayload<ExtArgs>, T, "findMany", GlobalOmitOptions> | Null>
|
unifiSites<T extends Prisma.Company$unifiSitesArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.Company$unifiSitesArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$UnifiSitePayload<ExtArgs>, T, "findMany", GlobalOmitOptions> | Null>
|
||||||
opportunities<T extends Prisma.Company$opportunitiesArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.Company$opportunitiesArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$OpportunityPayload<ExtArgs>, T, "findMany", GlobalOmitOptions> | Null>
|
opportunities<T extends Prisma.Company$opportunitiesArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.Company$opportunitiesArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$OpportunityPayload<ExtArgs>, T, "findMany", GlobalOmitOptions> | Null>
|
||||||
|
timeEntries<T extends Prisma.Company$timeEntriesArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.Company$timeEntriesArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$TimeEntryPayload<ExtArgs>, T, "findMany", GlobalOmitOptions> | Null>
|
||||||
|
activities<T extends Prisma.Company$activitiesArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.Company$activitiesArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$ActivityPayload<ExtArgs>, T, "findMany", GlobalOmitOptions> | Null>
|
||||||
deletedBy<T extends Prisma.Company$deletedByArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.Company$deletedByArgs<ExtArgs>>): Prisma.Prisma__UserClient<runtime.Types.Result.GetResult<Prisma.$UserPayload<ExtArgs>, T, "findUniqueOrThrow", GlobalOmitOptions> | null, null, ExtArgs, GlobalOmitOptions>
|
deletedBy<T extends Prisma.Company$deletedByArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.Company$deletedByArgs<ExtArgs>>): Prisma.Prisma__UserClient<runtime.Types.Result.GetResult<Prisma.$UserPayload<ExtArgs>, T, "findUniqueOrThrow", GlobalOmitOptions> | null, null, ExtArgs, GlobalOmitOptions>
|
||||||
enteredBy<T extends Prisma.Company$enteredByArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.Company$enteredByArgs<ExtArgs>>): Prisma.Prisma__UserClient<runtime.Types.Result.GetResult<Prisma.$UserPayload<ExtArgs>, T, "findUniqueOrThrow", GlobalOmitOptions> | null, null, ExtArgs, GlobalOmitOptions>
|
enteredBy<T extends Prisma.Company$enteredByArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.Company$enteredByArgs<ExtArgs>>): Prisma.Prisma__UserClient<runtime.Types.Result.GetResult<Prisma.$UserPayload<ExtArgs>, T, "findUniqueOrThrow", GlobalOmitOptions> | null, null, ExtArgs, GlobalOmitOptions>
|
||||||
serviceTickets<T extends Prisma.Company$serviceTicketsArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.Company$serviceTicketsArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$ServiceTicketPayload<ExtArgs>, T, "findMany", GlobalOmitOptions> | Null>
|
serviceTickets<T extends Prisma.Company$serviceTicketsArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.Company$serviceTicketsArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$ServiceTicketPayload<ExtArgs>, T, "findMany", GlobalOmitOptions> | Null>
|
||||||
@@ -3071,6 +3445,54 @@ export type Company$opportunitiesArgs<ExtArgs extends runtime.Types.Extensions.I
|
|||||||
distinct?: Prisma.OpportunityScalarFieldEnum | Prisma.OpportunityScalarFieldEnum[]
|
distinct?: Prisma.OpportunityScalarFieldEnum | Prisma.OpportunityScalarFieldEnum[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Company.timeEntries
|
||||||
|
*/
|
||||||
|
export type Company$timeEntriesArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||||
|
/**
|
||||||
|
* Select specific fields to fetch from the TimeEntry
|
||||||
|
*/
|
||||||
|
select?: Prisma.TimeEntrySelect<ExtArgs> | null
|
||||||
|
/**
|
||||||
|
* Omit specific fields from the TimeEntry
|
||||||
|
*/
|
||||||
|
omit?: Prisma.TimeEntryOmit<ExtArgs> | null
|
||||||
|
/**
|
||||||
|
* Choose, which related nodes to fetch as well
|
||||||
|
*/
|
||||||
|
include?: Prisma.TimeEntryInclude<ExtArgs> | null
|
||||||
|
where?: Prisma.TimeEntryWhereInput
|
||||||
|
orderBy?: Prisma.TimeEntryOrderByWithRelationInput | Prisma.TimeEntryOrderByWithRelationInput[]
|
||||||
|
cursor?: Prisma.TimeEntryWhereUniqueInput
|
||||||
|
take?: number
|
||||||
|
skip?: number
|
||||||
|
distinct?: Prisma.TimeEntryScalarFieldEnum | Prisma.TimeEntryScalarFieldEnum[]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Company.activities
|
||||||
|
*/
|
||||||
|
export type Company$activitiesArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||||
|
/**
|
||||||
|
* Select specific fields to fetch from the Activity
|
||||||
|
*/
|
||||||
|
select?: Prisma.ActivitySelect<ExtArgs> | null
|
||||||
|
/**
|
||||||
|
* Omit specific fields from the Activity
|
||||||
|
*/
|
||||||
|
omit?: Prisma.ActivityOmit<ExtArgs> | null
|
||||||
|
/**
|
||||||
|
* Choose, which related nodes to fetch as well
|
||||||
|
*/
|
||||||
|
include?: Prisma.ActivityInclude<ExtArgs> | null
|
||||||
|
where?: Prisma.ActivityWhereInput
|
||||||
|
orderBy?: Prisma.ActivityOrderByWithRelationInput | Prisma.ActivityOrderByWithRelationInput[]
|
||||||
|
cursor?: Prisma.ActivityWhereUniqueInput
|
||||||
|
take?: number
|
||||||
|
skip?: number
|
||||||
|
distinct?: Prisma.ActivityScalarFieldEnum | Prisma.ActivityScalarFieldEnum[]
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Company.deletedBy
|
* Company.deletedBy
|
||||||
*/
|
*/
|
||||||
|
|||||||
+289
-1
@@ -250,6 +250,7 @@ model CorporateLocation {
|
|||||||
opportunities Opportunity[]
|
opportunities Opportunity[]
|
||||||
serviceBoards ServiceTicketBoard[]
|
serviceBoards ServiceTicketBoard[]
|
||||||
productDataRecords ProductData[]
|
productDataRecords ProductData[]
|
||||||
|
timeEntries TimeEntry[]
|
||||||
|
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
@@ -307,6 +308,9 @@ model Company {
|
|||||||
credentials Credential[]
|
credentials Credential[]
|
||||||
unifiSites UnifiSite[]
|
unifiSites UnifiSite[]
|
||||||
opportunities Opportunity[]
|
opportunities Opportunity[]
|
||||||
|
timeEntries TimeEntry[]
|
||||||
|
|
||||||
|
activities Activity[]
|
||||||
|
|
||||||
deletedBy User? @relation("DeletedBy", fields: [deletedById], references: [cwIdentifier])
|
deletedBy User? @relation("DeletedBy", fields: [deletedById], references: [cwIdentifier])
|
||||||
enteredBy User? @relation("EnteredBy", fields: [enteredById], references: [cwIdentifier])
|
enteredBy User? @relation("EnteredBy", fields: [enteredById], references: [cwIdentifier])
|
||||||
@@ -385,11 +389,14 @@ model Contact {
|
|||||||
companyId Int?
|
companyId Int?
|
||||||
|
|
||||||
company Company? @relation(fields: [companyId], references: [id])
|
company Company? @relation(fields: [companyId], references: [id])
|
||||||
|
|
||||||
opportunities Opportunity[]
|
opportunities Opportunity[]
|
||||||
|
serviceTickets ServiceTicket[]
|
||||||
|
activities Activity[]
|
||||||
|
timeEntries TimeEntry[]
|
||||||
|
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
serviceTickets ServiceTicket[]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
model CatalogItemType {
|
model CatalogItemType {
|
||||||
@@ -693,6 +700,7 @@ model ServiceTicket {
|
|||||||
// ------ Billing and invoicing fields ------
|
// ------ Billing and invoicing fields ------
|
||||||
|
|
||||||
products ProductData[] // The products used on this ticket, which may be important for billing and invoicing, as well as reporting and analytics.
|
products ProductData[] // The products used on this ticket, which may be important for billing and invoicing, as well as reporting and analytics.
|
||||||
|
timeEntries TimeEntry[] // The time entries logged against this ticket.
|
||||||
|
|
||||||
poNumber String?
|
poNumber String?
|
||||||
billCompleteFlag Boolean @default(false) // Bill after ticket is closed, not allowing any billing while open.
|
billCompleteFlag Boolean @default(false) // Bill after ticket is closed, not allowing any billing while open.
|
||||||
@@ -1196,6 +1204,271 @@ model Schedule {
|
|||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------- Activities -------
|
||||||
|
|
||||||
|
model Activity {
|
||||||
|
id Int @unique
|
||||||
|
uid String @id @default(uuid())
|
||||||
|
|
||||||
|
subject String // Activity Title/Summary
|
||||||
|
|
||||||
|
notes ActivityNotes?
|
||||||
|
|
||||||
|
startTime DateTime //Full Date Time Value
|
||||||
|
endTime DateTime //Full Date Time Value
|
||||||
|
|
||||||
|
assignToId String
|
||||||
|
assignedById String
|
||||||
|
enteredBy String
|
||||||
|
|
||||||
|
automated Boolean @default(false)
|
||||||
|
closedFlag Boolean @default(false)
|
||||||
|
|
||||||
|
notifyCompleteFlag Boolean @default(false) // Should we send a notification to the person assigned when activity is completed.
|
||||||
|
notificationSentFlat Boolean @default(false) // Tracks to see if the completion notification has already been sent out.
|
||||||
|
|
||||||
|
opportunityId String?
|
||||||
|
serviceTicketId String?
|
||||||
|
|
||||||
|
contactId Int?
|
||||||
|
companyId Int?
|
||||||
|
activityTypeId Int?
|
||||||
|
activityStatusId Int?
|
||||||
|
|
||||||
|
contact Contact? @relation(fields: [contactId], references: [id])
|
||||||
|
company Company? @relation(fields: [companyId], references: [id])
|
||||||
|
activityType ActivityType? @relation(fields: [activityTypeId], references: [id])
|
||||||
|
activityStatus ActivityStatus? @relation(fields: [activityStatusId], references: [id])
|
||||||
|
|
||||||
|
timeEntries TimeEntry[]
|
||||||
|
|
||||||
|
createdById String?
|
||||||
|
updatedById String?
|
||||||
|
closedById String?
|
||||||
|
|
||||||
|
closedAt DateTime?
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
}
|
||||||
|
|
||||||
|
model ActivityNotes {
|
||||||
|
id Int @unique
|
||||||
|
uid String @id @default(uuid())
|
||||||
|
|
||||||
|
notes String @default("")
|
||||||
|
|
||||||
|
activityId Int? @unique
|
||||||
|
activity Activity? @relation(fields: [activityId], references: [id])
|
||||||
|
|
||||||
|
internalAnalysisFlag Boolean @default(false) // Does this note describing the internal analysis of the activity, such as root cause analysis or technical details that may not be relevant to the customer?
|
||||||
|
|
||||||
|
enteredById String?
|
||||||
|
updatedById String?
|
||||||
|
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
}
|
||||||
|
|
||||||
|
model ActivityType {
|
||||||
|
id Int @unique
|
||||||
|
uid String @id @default(uuid())
|
||||||
|
|
||||||
|
name String @db.VarChar(15) // "SO_Activity_Type_ID" in CW
|
||||||
|
description String
|
||||||
|
|
||||||
|
inactiveFlag Boolean @default(false)
|
||||||
|
historyFlag Boolean @default(false) // Is this activity type just for historical record keeping, and should not be used for new activities?
|
||||||
|
|
||||||
|
defaultFlag Boolean @default(false)
|
||||||
|
importFlag Boolean @default(false)
|
||||||
|
emailFlag Boolean @default(false)
|
||||||
|
memoFlag Boolean @default(false)
|
||||||
|
|
||||||
|
pointsValue Int?
|
||||||
|
|
||||||
|
activities Activity[]
|
||||||
|
|
||||||
|
updatedById String?
|
||||||
|
createdById String?
|
||||||
|
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
}
|
||||||
|
|
||||||
|
model ActivityStatus {
|
||||||
|
id Int @unique
|
||||||
|
uid String @id @default(uuid())
|
||||||
|
|
||||||
|
name String
|
||||||
|
description String? // Optima Only field, not synced to CW
|
||||||
|
|
||||||
|
closedFlag Boolean @default(false)
|
||||||
|
inactiveFlag Boolean @default(false)
|
||||||
|
defaultFlag Boolean @default(false)
|
||||||
|
spawnFollowupFlag Boolean @default(false) // Should creating an activity with this status automatically spawn a follow-up activity with a different type and/or status?
|
||||||
|
|
||||||
|
activities Activity[]
|
||||||
|
|
||||||
|
updatedById String?
|
||||||
|
createdById String?
|
||||||
|
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------- Time Entries -------
|
||||||
|
|
||||||
|
model TimeEntry {
|
||||||
|
id Int @unique
|
||||||
|
uid String @id @default(uuid())
|
||||||
|
|
||||||
|
// The CW member identifier of the person who logged this time
|
||||||
|
memberId String?
|
||||||
|
|
||||||
|
// Relational Values
|
||||||
|
serviceTicketId Int?
|
||||||
|
activityId Int?
|
||||||
|
projectId Int? // TODO: Implement this.
|
||||||
|
chargeCodeId Int?
|
||||||
|
companyId Int
|
||||||
|
statusId Int?
|
||||||
|
locationId Int?
|
||||||
|
contactId Int?
|
||||||
|
|
||||||
|
contact Contact? @relation(fields: [contactId], references: [id])
|
||||||
|
location CorporateLocation? @relation(fields: [locationId], references: [id])
|
||||||
|
status TimeEntryStatus? @relation(fields: [statusId], references: [id])
|
||||||
|
chargeCode TimeEntryChargeCode? @relation(fields: [chargeCodeId], references: [id])
|
||||||
|
company Company @relation(fields: [companyId], references: [id])
|
||||||
|
serviceTicket ServiceTicket? @relation(fields: [serviceTicketId], references: [id])
|
||||||
|
activity Activity? @relation(fields: [activityId], references: [id])
|
||||||
|
|
||||||
|
// ------ Time Fields ------
|
||||||
|
|
||||||
|
dateStart DateTime?
|
||||||
|
timeStart DateTime?
|
||||||
|
timeEnd DateTime?
|
||||||
|
|
||||||
|
// ------ Notes ------
|
||||||
|
|
||||||
|
notes String? // Customer-visible notes about what was done
|
||||||
|
notesMd String? // Markdown version of notes
|
||||||
|
internalNote String? // Internal notes not visible to the customer
|
||||||
|
|
||||||
|
// ------ Hours ------
|
||||||
|
|
||||||
|
billableHours Float? // How many hours are being billed to the customer
|
||||||
|
actualHours Float? // How many hours were actually worked
|
||||||
|
invoicedHours Float? // How many hours have been included on an invoice
|
||||||
|
deductedHours Float? // How many hours were deducted from billing, but not necessarily the same as actual hours if there are any adjustments or overrides.
|
||||||
|
|
||||||
|
// ------ Rates ------
|
||||||
|
|
||||||
|
hourlyRate Float? // The rate at which this time is billed to the customer
|
||||||
|
effectiveRate Float? // The actual effective rate after any agreement or override adjustments
|
||||||
|
|
||||||
|
// ------ Flag Fields ------
|
||||||
|
|
||||||
|
issueFlag Boolean @default(false)
|
||||||
|
mergedFlag Boolean @default(false) // Has this time entry been merged with another time entry, such as when multiple time entries are combined into one for billing purposes?
|
||||||
|
invoiceFlag Boolean @default(false) // Has this time entry been included on an invoice?
|
||||||
|
billableFlag Boolean @default(true) // Should this time entry be billed to the customer?
|
||||||
|
documentFlag Boolean @default(false) // Is there a document associated with this time entry, such as a receipt for an expense or a report of the work done?
|
||||||
|
teProblemFlag Boolean @default(false) // Does this note describe the problem?
|
||||||
|
teResolutionFlag Boolean @default(false) // Does this note describe the resolution?
|
||||||
|
teInternalAnalysisFlag Boolean @default(false) // Does this note contain internal analysis?
|
||||||
|
|
||||||
|
// ------ Audit Fields ------
|
||||||
|
|
||||||
|
chargeToRecId Int? // The record ID of the entity that this time entry should be charged to, which may be used for billing and reporting purposes, and may be different from the service ticket or activity it is associated with.
|
||||||
|
chargeToType String? @db.VarChar(13)
|
||||||
|
|
||||||
|
createdById String?
|
||||||
|
updatedById String?
|
||||||
|
originalAuthorId String?
|
||||||
|
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
}
|
||||||
|
|
||||||
|
model TimeEntryStatus {
|
||||||
|
id Int @unique
|
||||||
|
uid String @id @default(uuid())
|
||||||
|
|
||||||
|
statusId Int @unique
|
||||||
|
description String? @db.VarChar(50)
|
||||||
|
action String?
|
||||||
|
|
||||||
|
timeEntries TimeEntry[]
|
||||||
|
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
}
|
||||||
|
|
||||||
|
model TimeEntryChargeCode {
|
||||||
|
id Int @unique
|
||||||
|
uid String @id @default(uuid())
|
||||||
|
|
||||||
|
chargeCodeId Int @unique
|
||||||
|
description String? @db.VarChar(50)
|
||||||
|
|
||||||
|
expenseFlag Boolean @default(false)
|
||||||
|
timeFlag Boolean @default(true)
|
||||||
|
billableFlag Boolean @default(true)
|
||||||
|
invoiceFlag Boolean @default(true)
|
||||||
|
|
||||||
|
timeEntries TimeEntry[]
|
||||||
|
|
||||||
|
updatedById String?
|
||||||
|
createdById String?
|
||||||
|
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
}
|
||||||
|
|
||||||
|
model TimeActivityClass {
|
||||||
|
id Int @unique
|
||||||
|
uid String @id @default(uuid())
|
||||||
|
|
||||||
|
description String? @db.VarChar(50)
|
||||||
|
hourlyRate Float?
|
||||||
|
|
||||||
|
inactiveFlag Boolean @default(false)
|
||||||
|
taxExemptFlag Boolean @default(false)
|
||||||
|
|
||||||
|
createdById String?
|
||||||
|
updatedById String?
|
||||||
|
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
}
|
||||||
|
|
||||||
|
model TimeActivityType {
|
||||||
|
id Int @unique
|
||||||
|
uid String @id @default(uuid())
|
||||||
|
|
||||||
|
description String? @db.VarChar(50)
|
||||||
|
|
||||||
|
minHours Float?
|
||||||
|
maxHours Float?
|
||||||
|
|
||||||
|
rate Float? @default(1)
|
||||||
|
costMultiplier Float @default(1)
|
||||||
|
|
||||||
|
inactiveFlag Boolean @default(false)
|
||||||
|
invoiceFlag Boolean @default(false)
|
||||||
|
billableFlag Boolean @default(false)
|
||||||
|
utilizationFlag Boolean @default(false)
|
||||||
|
defaultFlag Boolean @default(false)
|
||||||
|
multiplierFlag Boolean @default(false)
|
||||||
|
|
||||||
|
createdById String?
|
||||||
|
updatedById String?
|
||||||
|
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
}
|
||||||
|
|
||||||
model CredentialType {
|
model CredentialType {
|
||||||
id String @id @default(cuid())
|
id String @id @default(cuid())
|
||||||
name String @unique
|
name String @unique
|
||||||
@@ -1307,3 +1580,18 @@ model CwMember {
|
|||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
model CwMemberType {
|
||||||
|
id Int @unique
|
||||||
|
uid String @id @default(uuid())
|
||||||
|
|
||||||
|
description String? @db.VarChar(30)
|
||||||
|
|
||||||
|
inactiveFlag Boolean @default(false)
|
||||||
|
|
||||||
|
updatedById String?
|
||||||
|
createdById String?
|
||||||
|
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import { Hono } from "hono";
|
||||||
|
import * as timeEntryRoutes from "../time-entries";
|
||||||
|
|
||||||
|
const timeEntryRouter = new Hono();
|
||||||
|
Object.values(timeEntryRoutes).map((r) => timeEntryRouter.route("/", r));
|
||||||
|
|
||||||
|
export default timeEntryRouter;
|
||||||
@@ -3,6 +3,7 @@ import { apiResponse } from "../../../../../modules/api-utils/apiResponse";
|
|||||||
import { ContentfulStatusCode } from "hono/utils/http-status";
|
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||||
import { authMiddleware } from "../../../../middleware/authorization";
|
import { authMiddleware } from "../../../../middleware/authorization";
|
||||||
import { opportunities } from "../../../../../managers/opportunities";
|
import { opportunities } from "../../../../../managers/opportunities";
|
||||||
|
import { timeEntries } from "../../../../../managers/timeEntries";
|
||||||
import { activityCw } from "../../../../../modules/cw-utils/activities/activities";
|
import { activityCw } from "../../../../../modules/cw-utils/activities/activities";
|
||||||
import { ActivityController } from "../../../../../controllers/ActivityController";
|
import { ActivityController } from "../../../../../controllers/ActivityController";
|
||||||
import { OptimaType } from "../../../../../workflows/wf.opportunity";
|
import { OptimaType } from "../../../../../workflows/wf.opportunity";
|
||||||
@@ -31,6 +32,9 @@ const QUOTE_ID_FIELD_ID = 48;
|
|||||||
/** Close Date custom field ID (matches wf.opportunity.ts CLOSE_DATE_FIELD_ID). */
|
/** Close Date custom field ID (matches wf.opportunity.ts CLOSE_DATE_FIELD_ID). */
|
||||||
const CLOSE_DATE_FIELD_ID = 49;
|
const CLOSE_DATE_FIELD_ID = 49;
|
||||||
|
|
||||||
|
/** Parent_Activity custom field ID. */
|
||||||
|
const PARENT_ACTIVITY_FIELD_ID = 50;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract the Optima_Type value from a CW activity's custom fields.
|
* Extract the Optima_Type value from a CW activity's custom fields.
|
||||||
* Returns the string value if present, or null.
|
* Returns the string value if present, or null.
|
||||||
@@ -70,6 +74,22 @@ function extractCloseDate(
|
|||||||
return field.value;
|
return field.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract the Parent_Activity custom field value from a CW activity.
|
||||||
|
* Returns the numeric activity ID or null.
|
||||||
|
*/
|
||||||
|
function extractParentActivityId(
|
||||||
|
customFields: { id: number; value: unknown }[] | undefined,
|
||||||
|
): number | null {
|
||||||
|
if (!customFields) return null;
|
||||||
|
const field = customFields.find(
|
||||||
|
(f) => f.id === PARENT_ACTIVITY_FIELD_ID || (f as any).caption === "Parent_Activity",
|
||||||
|
);
|
||||||
|
if (!field?.value) return null;
|
||||||
|
const parsed = parseInt(String(field.value), 10);
|
||||||
|
return isNaN(parsed) ? null : parsed;
|
||||||
|
}
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════════════════
|
||||||
// ROUTE
|
// ROUTE
|
||||||
// ═══════════════════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════════════════
|
||||||
@@ -96,6 +116,7 @@ export default createRoute(
|
|||||||
activity: ReturnType<ActivityController["toJson"]>;
|
activity: ReturnType<ActivityController["toJson"]>;
|
||||||
optimaType: string;
|
optimaType: string;
|
||||||
quoteId: string | null;
|
quoteId: string | null;
|
||||||
|
parentActivityId: number | null;
|
||||||
closed: boolean;
|
closed: boolean;
|
||||||
closedAt: string | null;
|
closedAt: string | null;
|
||||||
}[] = [];
|
}[] = [];
|
||||||
@@ -109,6 +130,7 @@ export default createRoute(
|
|||||||
if (filterType && optimaType !== filterType) continue;
|
if (filterType && optimaType !== filterType) continue;
|
||||||
|
|
||||||
const quoteId = extractQuoteId(raw.customFields);
|
const quoteId = extractQuoteId(raw.customFields);
|
||||||
|
const parentActivityId = extractParentActivityId(raw.customFields);
|
||||||
const closed = raw.status?.id === 2;
|
const closed = raw.status?.id === 2;
|
||||||
const closedAt = extractCloseDate(raw.customFields);
|
const closedAt = extractCloseDate(raw.customFields);
|
||||||
|
|
||||||
@@ -116,6 +138,7 @@ export default createRoute(
|
|||||||
activity: json,
|
activity: json,
|
||||||
optimaType,
|
optimaType,
|
||||||
quoteId,
|
quoteId,
|
||||||
|
parentActivityId,
|
||||||
closed,
|
closed,
|
||||||
closedAt,
|
closedAt,
|
||||||
});
|
});
|
||||||
@@ -132,13 +155,26 @@ export default createRoute(
|
|||||||
return dateB - dateA;
|
return dateB - dateA;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Attach time entries for each activity in parallel
|
||||||
|
const activitiesWithTimeEntries = await Promise.all(
|
||||||
|
workflowActivities.map(async (item) => {
|
||||||
|
const entries = await timeEntries.fetchByActivity(
|
||||||
|
item.activity.cwActivityId,
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
timeEntries: entries.map((e) => e.toJson()),
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
const response = apiResponse.successful(
|
const response = apiResponse.successful(
|
||||||
"Workflow history fetched successfully.",
|
"Workflow history fetched successfully.",
|
||||||
{
|
{
|
||||||
opportunityId: opportunity.id,
|
opportunityId: opportunity.id,
|
||||||
cwOpportunityId: opportunity.cwOpportunityId,
|
cwOpportunityId: opportunity.cwOpportunityId,
|
||||||
totalActivities: workflowActivities.length,
|
totalActivities: activitiesWithTimeEntries.length,
|
||||||
activities: workflowActivities,
|
activities: activitiesWithTimeEntries,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
return c.json(response, response.status as ContentfulStatusCode);
|
return c.json(response, response.status as ContentfulStatusCode);
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import procurementRouter from "./routers/procurementRouter";
|
|||||||
import salesRouter from "./routers/salesRouter";
|
import salesRouter from "./routers/salesRouter";
|
||||||
import cwRouter from "./routers/cwRouter";
|
import cwRouter from "./routers/cwRouter";
|
||||||
import scheduleRouter from "./routers/scheduleRouter";
|
import scheduleRouter from "./routers/scheduleRouter";
|
||||||
|
import timeEntryRouter from "./routers/timeEntryRouter";
|
||||||
|
|
||||||
const app = new Hono();
|
const app = new Hono();
|
||||||
const v1 = new Hono();
|
const v1 = new Hono();
|
||||||
@@ -73,6 +74,7 @@ v1.route("/procurement", procurementRouter);
|
|||||||
v1.route("/sales", salesRouter);
|
v1.route("/sales", salesRouter);
|
||||||
v1.route("/cw", cwRouter);
|
v1.route("/cw", cwRouter);
|
||||||
v1.route("/schedule", scheduleRouter);
|
v1.route("/schedule", scheduleRouter);
|
||||||
|
v1.route("/time-entry", timeEntryRouter);
|
||||||
app.route("/v1", v1);
|
app.route("/v1", v1);
|
||||||
|
|
||||||
export default app;
|
export default app;
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import { createRoute } from "../../../modules/api-utils/createRoute";
|
||||||
|
import { timeEntries } from "../../../managers/timeEntries";
|
||||||
|
import { apiResponse } from "../../../modules/api-utils/apiResponse";
|
||||||
|
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||||
|
import { authMiddleware } from "../../middleware/authorization";
|
||||||
|
|
||||||
|
/* GET /v1/time-entry/time-entries/:identifier */
|
||||||
|
export default createRoute(
|
||||||
|
"get",
|
||||||
|
["/time-entries/:identifier"],
|
||||||
|
async (c) => {
|
||||||
|
const entry = await timeEntries.fetch(c.req.param("identifier"));
|
||||||
|
|
||||||
|
const response = apiResponse.successful(
|
||||||
|
"Time entry fetched successfully!",
|
||||||
|
entry.toJson(),
|
||||||
|
);
|
||||||
|
|
||||||
|
return c.json(response, response.status as ContentfulStatusCode);
|
||||||
|
},
|
||||||
|
authMiddleware({ permissions: ["time-entry.fetch"] }),
|
||||||
|
);
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import { createRoute } from "../../modules/api-utils/createRoute";
|
||||||
|
import { timeEntries } from "../../managers/timeEntries";
|
||||||
|
import { apiResponse } from "../../modules/api-utils/apiResponse";
|
||||||
|
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||||
|
import { authMiddleware } from "../middleware/authorization";
|
||||||
|
|
||||||
|
/* GET /v1/time-entry/count */
|
||||||
|
export default createRoute(
|
||||||
|
"get",
|
||||||
|
["/count"],
|
||||||
|
async (c) => {
|
||||||
|
const count = await timeEntries.count();
|
||||||
|
|
||||||
|
const response = apiResponse.successful(
|
||||||
|
"Time entry count fetched successfully!",
|
||||||
|
{ count },
|
||||||
|
);
|
||||||
|
|
||||||
|
return c.json(response, response.status as ContentfulStatusCode);
|
||||||
|
},
|
||||||
|
authMiddleware({ permissions: ["time-entry.fetch.many"] }),
|
||||||
|
);
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
import { createRoute } from "../../modules/api-utils/createRoute";
|
||||||
|
import { timeEntries } from "../../managers/timeEntries";
|
||||||
|
import { apiResponse } from "../../modules/api-utils/apiResponse";
|
||||||
|
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||||
|
import { authMiddleware } from "../middleware/authorization";
|
||||||
|
|
||||||
|
/* GET /v1/time-entry/time-entries?page=&rpp=&search= */
|
||||||
|
export default createRoute(
|
||||||
|
"get",
|
||||||
|
["/time-entries"],
|
||||||
|
async (c) => {
|
||||||
|
const page = new Number(c.req.query("page") ?? 1) as number;
|
||||||
|
const rpp = new Number(c.req.query("rpp") ?? 30) as number;
|
||||||
|
const search = c.req.query("search");
|
||||||
|
|
||||||
|
const data = search
|
||||||
|
? await timeEntries.search(search, page, rpp)
|
||||||
|
: await timeEntries.fetchPages(page, rpp);
|
||||||
|
|
||||||
|
const totalRecords = search
|
||||||
|
? (await timeEntries.search(search, 1, 999999)).length
|
||||||
|
: await timeEntries.count();
|
||||||
|
|
||||||
|
const response = apiResponse.successful(
|
||||||
|
"Time entries fetched successfully!",
|
||||||
|
data.map((e) => e.toJson()),
|
||||||
|
{
|
||||||
|
pagination: {
|
||||||
|
previousPage: page == 1 ? null : page - 1,
|
||||||
|
currentPage: page,
|
||||||
|
nextPage: page >= totalRecords / rpp ? null : page + 1,
|
||||||
|
totalPages: Math.ceil(totalRecords / rpp),
|
||||||
|
totalRecords,
|
||||||
|
listedRecords: rpp,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
return c.json(response, response.status as ContentfulStatusCode);
|
||||||
|
},
|
||||||
|
authMiddleware({ permissions: ["time-entry.fetch.many"] }),
|
||||||
|
);
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
import { default as fetchAll } from "./fetchAll";
|
||||||
|
import { default as count } from "./count";
|
||||||
|
import { default as fetch } from "./[identifier]/fetch";
|
||||||
|
import { default as fetchByMember } from "./member/fetchByMember";
|
||||||
|
import { default as fetchByTicket } from "./ticket/fetchByTicket";
|
||||||
|
import { default as fetchMyTimeEntries } from "./me/fetchMyTimeEntries";
|
||||||
|
|
||||||
|
export { count, fetch, fetchAll, fetchByMember, fetchByTicket, fetchMyTimeEntries };
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
import { createRoute } from "../../../modules/api-utils/createRoute";
|
||||||
|
import { timeEntries } from "../../../managers/timeEntries";
|
||||||
|
import { apiResponse } from "../../../modules/api-utils/apiResponse";
|
||||||
|
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||||
|
import { authMiddleware } from "../../middleware/authorization";
|
||||||
|
import GenericError from "../../../Errors/GenericError";
|
||||||
|
|
||||||
|
/* GET /v1/time-entry/@me?start=<ISO>&end=<ISO> */
|
||||||
|
export default createRoute(
|
||||||
|
"get",
|
||||||
|
["/@me"],
|
||||||
|
async (c) => {
|
||||||
|
const user = c.get("user");
|
||||||
|
|
||||||
|
if (!user?.cwIdentifier) {
|
||||||
|
throw new GenericError({
|
||||||
|
name: "BadRequest",
|
||||||
|
message:
|
||||||
|
"Your account is not linked to a ConnectWise member. Cannot fetch time entries.",
|
||||||
|
status: 400,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const startParam = c.req.query("start");
|
||||||
|
const endParam = c.req.query("end");
|
||||||
|
|
||||||
|
if (!startParam || !endParam) {
|
||||||
|
throw new GenericError({
|
||||||
|
name: "BadRequest",
|
||||||
|
message:
|
||||||
|
"Query params 'start' and 'end' are required (ISO 8601 date strings).",
|
||||||
|
status: 400,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const startDate = new Date(startParam);
|
||||||
|
const endDate = new Date(endParam);
|
||||||
|
|
||||||
|
if (isNaN(startDate.getTime()) || isNaN(endDate.getTime())) {
|
||||||
|
throw new GenericError({
|
||||||
|
name: "BadRequest",
|
||||||
|
message: "Invalid date format. Use ISO 8601 (e.g. 2026-04-01T00:00:00Z).",
|
||||||
|
status: 400,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startDate >= endDate) {
|
||||||
|
throw new GenericError({
|
||||||
|
name: "BadRequest",
|
||||||
|
message: "'start' must be before 'end'.",
|
||||||
|
status: 400,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await timeEntries.fetchByDateRange(
|
||||||
|
startDate,
|
||||||
|
endDate,
|
||||||
|
user.cwIdentifier,
|
||||||
|
);
|
||||||
|
|
||||||
|
const response = apiResponse.successful(
|
||||||
|
"Time entries fetched successfully!",
|
||||||
|
data.map((e) => e.toJson()),
|
||||||
|
);
|
||||||
|
|
||||||
|
return c.json(response, response.status as ContentfulStatusCode);
|
||||||
|
},
|
||||||
|
authMiddleware({ permissions: ["time-entry.fetch"] }),
|
||||||
|
);
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
import { createRoute } from "../../../modules/api-utils/createRoute";
|
||||||
|
import { timeEntries } from "../../../managers/timeEntries";
|
||||||
|
import { apiResponse } from "../../../modules/api-utils/apiResponse";
|
||||||
|
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||||
|
import { authMiddleware } from "../../middleware/authorization";
|
||||||
|
|
||||||
|
/* GET /v1/time-entry/member/:memberId?page=&rpp= */
|
||||||
|
export default createRoute(
|
||||||
|
"get",
|
||||||
|
["/member/:memberId"],
|
||||||
|
async (c) => {
|
||||||
|
const memberId = c.req.param("memberId");
|
||||||
|
const page = new Number(c.req.query("page") ?? 1) as number;
|
||||||
|
const rpp = new Number(c.req.query("rpp") ?? 30) as number;
|
||||||
|
|
||||||
|
const data = await timeEntries.fetchByMember(memberId, page, rpp);
|
||||||
|
const totalRecords = await timeEntries.countByMember(memberId);
|
||||||
|
|
||||||
|
const response = apiResponse.successful(
|
||||||
|
"Time entries fetched successfully!",
|
||||||
|
data.map((e) => e.toJson()),
|
||||||
|
{
|
||||||
|
pagination: {
|
||||||
|
previousPage: page == 1 ? null : page - 1,
|
||||||
|
currentPage: page,
|
||||||
|
nextPage: page >= totalRecords / rpp ? null : page + 1,
|
||||||
|
totalPages: Math.ceil(totalRecords / rpp),
|
||||||
|
totalRecords,
|
||||||
|
listedRecords: rpp,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
return c.json(response, response.status as ContentfulStatusCode);
|
||||||
|
},
|
||||||
|
authMiddleware({ permissions: ["time-entry.fetch.many"] }),
|
||||||
|
);
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import { createRoute } from "../../../modules/api-utils/createRoute";
|
||||||
|
import { timeEntries } from "../../../managers/timeEntries";
|
||||||
|
import { apiResponse } from "../../../modules/api-utils/apiResponse";
|
||||||
|
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||||
|
import { authMiddleware } from "../../middleware/authorization";
|
||||||
|
|
||||||
|
/* GET /v1/time-entry/ticket/:ticketId */
|
||||||
|
export default createRoute(
|
||||||
|
"get",
|
||||||
|
["/ticket/:ticketId"],
|
||||||
|
async (c) => {
|
||||||
|
const ticketId = parseInt(c.req.param("ticketId"), 10);
|
||||||
|
|
||||||
|
const data = await timeEntries.fetchByTicket(ticketId);
|
||||||
|
|
||||||
|
const response = apiResponse.successful(
|
||||||
|
"Time entries fetched successfully!",
|
||||||
|
data.map((e) => e.toJson()),
|
||||||
|
);
|
||||||
|
|
||||||
|
return c.json(response, response.status as ContentfulStatusCode);
|
||||||
|
},
|
||||||
|
authMiddleware({ permissions: ["time-entry.fetch.many"] }),
|
||||||
|
);
|
||||||
@@ -0,0 +1,131 @@
|
|||||||
|
import {
|
||||||
|
TimeEntry,
|
||||||
|
TimeEntryStatus,
|
||||||
|
TimeEntryChargeCode,
|
||||||
|
Company,
|
||||||
|
ServiceTicket,
|
||||||
|
Activity,
|
||||||
|
Contact,
|
||||||
|
CorporateLocation,
|
||||||
|
} from "../../generated/prisma/client";
|
||||||
|
|
||||||
|
type TimeEntryWithRelations = TimeEntry & {
|
||||||
|
status?: TimeEntryStatus | null;
|
||||||
|
chargeCode?: TimeEntryChargeCode | null;
|
||||||
|
company?: Company | null;
|
||||||
|
serviceTicket?: ServiceTicket | null;
|
||||||
|
activity?: Activity | null;
|
||||||
|
contact?: Contact | null;
|
||||||
|
location?: CorporateLocation | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export class TimeEntryController {
|
||||||
|
public readonly id: number;
|
||||||
|
public readonly uid: string;
|
||||||
|
|
||||||
|
private _data: TimeEntryWithRelations;
|
||||||
|
|
||||||
|
constructor(data: TimeEntryWithRelations) {
|
||||||
|
this.id = data.id;
|
||||||
|
this.uid = data.uid;
|
||||||
|
this._data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public toJson() {
|
||||||
|
const d = this._data;
|
||||||
|
return {
|
||||||
|
id: d.uid,
|
||||||
|
cwId: d.id,
|
||||||
|
memberId: d.memberId,
|
||||||
|
|
||||||
|
// ------ Time Fields ------
|
||||||
|
dateStart: d.dateStart,
|
||||||
|
timeStart: d.timeStart,
|
||||||
|
timeEnd: d.timeEnd,
|
||||||
|
|
||||||
|
// ------ Notes ------
|
||||||
|
notes: d.notes,
|
||||||
|
notesMd: d.notesMd,
|
||||||
|
internalNote: d.internalNote,
|
||||||
|
|
||||||
|
// ------ Hours ------
|
||||||
|
billableHours: d.billableHours,
|
||||||
|
actualHours: d.actualHours,
|
||||||
|
invoicedHours: d.invoicedHours,
|
||||||
|
deductedHours: d.deductedHours,
|
||||||
|
|
||||||
|
// ------ Rates ------
|
||||||
|
hourlyRate: d.hourlyRate,
|
||||||
|
effectiveRate: d.effectiveRate,
|
||||||
|
|
||||||
|
// ------ Flag Fields ------
|
||||||
|
issueFlag: d.issueFlag,
|
||||||
|
mergedFlag: d.mergedFlag,
|
||||||
|
invoiceFlag: d.invoiceFlag,
|
||||||
|
billableFlag: d.billableFlag,
|
||||||
|
documentFlag: d.documentFlag,
|
||||||
|
teProblemFlag: d.teProblemFlag,
|
||||||
|
teResolutionFlag: d.teResolutionFlag,
|
||||||
|
teInternalAnalysisFlag: d.teInternalAnalysisFlag,
|
||||||
|
|
||||||
|
// ------ Charge Info ------
|
||||||
|
chargeToRecId: d.chargeToRecId,
|
||||||
|
chargeToType: d.chargeToType,
|
||||||
|
|
||||||
|
// ------ Relations ------
|
||||||
|
company: d.company
|
||||||
|
? { id: d.company.uid, cwId: d.company.id, name: d.company.name }
|
||||||
|
: null,
|
||||||
|
serviceTicket: d.serviceTicket
|
||||||
|
? {
|
||||||
|
id: d.serviceTicket.uid,
|
||||||
|
cwId: d.serviceTicket.id,
|
||||||
|
summary: d.serviceTicket.summary,
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
activity: d.activity
|
||||||
|
? {
|
||||||
|
id: d.activity.uid,
|
||||||
|
cwId: d.activity.id,
|
||||||
|
subject: d.activity.subject,
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
contact: d.contact
|
||||||
|
? {
|
||||||
|
id: d.contact.uid,
|
||||||
|
cwId: d.contact.id,
|
||||||
|
name: `${d.contact.firstName} ${d.contact.lastName}`.trim(),
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
location: d.location
|
||||||
|
? { id: d.location.uid, cwId: d.location.id, name: d.location.name }
|
||||||
|
: null,
|
||||||
|
status: d.status
|
||||||
|
? {
|
||||||
|
id: d.status.uid,
|
||||||
|
cwId: d.status.id,
|
||||||
|
description: d.status.description,
|
||||||
|
action: d.status.action,
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
chargeCode: d.chargeCode
|
||||||
|
? {
|
||||||
|
id: d.chargeCode.uid,
|
||||||
|
cwId: d.chargeCode.id,
|
||||||
|
description: d.chargeCode.description,
|
||||||
|
expenseFlag: d.chargeCode.expenseFlag,
|
||||||
|
timeFlag: d.chargeCode.timeFlag,
|
||||||
|
billableFlag: d.chargeCode.billableFlag,
|
||||||
|
invoiceFlag: d.chargeCode.invoiceFlag,
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
|
||||||
|
// ------ Audit ------
|
||||||
|
createdById: d.createdById,
|
||||||
|
updatedById: d.updatedById,
|
||||||
|
originalAuthorId: d.originalAuthorId,
|
||||||
|
createdAt: d.createdAt,
|
||||||
|
updatedAt: d.updatedAt,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,147 @@
|
|||||||
|
import { prisma } from "../constants";
|
||||||
|
import { TimeEntryController } from "../controllers/TimeEntryController";
|
||||||
|
|
||||||
|
const timeEntryIncludes = {
|
||||||
|
status: true,
|
||||||
|
chargeCode: true,
|
||||||
|
company: true,
|
||||||
|
serviceTicket: true,
|
||||||
|
activity: true,
|
||||||
|
contact: true,
|
||||||
|
location: true,
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export const timeEntries = {
|
||||||
|
async fetch(identifier: string | number): Promise<TimeEntryController> {
|
||||||
|
const isNumeric =
|
||||||
|
typeof identifier === "number" || /^\d+$/.test(String(identifier));
|
||||||
|
|
||||||
|
const entry = await prisma.timeEntry.findFirst({
|
||||||
|
where: isNumeric
|
||||||
|
? { id: Number(identifier) }
|
||||||
|
: { uid: String(identifier) },
|
||||||
|
include: timeEntryIncludes,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!entry) throw new Error("Unknown time entry.");
|
||||||
|
|
||||||
|
return new TimeEntryController(entry);
|
||||||
|
},
|
||||||
|
|
||||||
|
async count(): Promise<number> {
|
||||||
|
return prisma.timeEntry.count();
|
||||||
|
},
|
||||||
|
|
||||||
|
async fetchPages(page: number, rpp: number): Promise<TimeEntryController[]> {
|
||||||
|
page = page.valueOf();
|
||||||
|
rpp = rpp.valueOf();
|
||||||
|
|
||||||
|
const skip = (page > 1 ? page - 1 : 0) * rpp;
|
||||||
|
const take = rpp ?? 30;
|
||||||
|
|
||||||
|
const data = await prisma.timeEntry.findMany({
|
||||||
|
skip,
|
||||||
|
take,
|
||||||
|
include: timeEntryIncludes,
|
||||||
|
orderBy: { dateStart: "desc" },
|
||||||
|
});
|
||||||
|
|
||||||
|
return data.map((e) => new TimeEntryController(e));
|
||||||
|
},
|
||||||
|
|
||||||
|
async search(
|
||||||
|
query: string,
|
||||||
|
page: number,
|
||||||
|
rpp: number
|
||||||
|
): Promise<TimeEntryController[]> {
|
||||||
|
page = page.valueOf();
|
||||||
|
rpp = rpp.valueOf();
|
||||||
|
|
||||||
|
const skip = (page > 1 ? page - 1 : 0) * rpp;
|
||||||
|
const take = rpp ?? 30;
|
||||||
|
|
||||||
|
const numericQuery = parseInt(query, 10);
|
||||||
|
|
||||||
|
const data = await prisma.timeEntry.findMany({
|
||||||
|
where: {
|
||||||
|
OR: [
|
||||||
|
{ notes: { contains: query, mode: "insensitive" } },
|
||||||
|
{ internalNote: { contains: query, mode: "insensitive" } },
|
||||||
|
{ uid: { contains: query, mode: "insensitive" } },
|
||||||
|
...(!isNaN(numericQuery) ? [{ id: numericQuery }] : []),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
skip,
|
||||||
|
take,
|
||||||
|
include: timeEntryIncludes,
|
||||||
|
orderBy: { dateStart: "desc" },
|
||||||
|
});
|
||||||
|
|
||||||
|
return data.map((e) => new TimeEntryController(e));
|
||||||
|
},
|
||||||
|
|
||||||
|
async fetchByMember(
|
||||||
|
memberId: string,
|
||||||
|
page: number,
|
||||||
|
rpp: number
|
||||||
|
): Promise<TimeEntryController[]> {
|
||||||
|
page = page.valueOf();
|
||||||
|
rpp = rpp.valueOf();
|
||||||
|
|
||||||
|
const skip = (page > 1 ? page - 1 : 0) * rpp;
|
||||||
|
const take = rpp ?? 30;
|
||||||
|
|
||||||
|
const data = await prisma.timeEntry.findMany({
|
||||||
|
where: { memberId },
|
||||||
|
skip,
|
||||||
|
take,
|
||||||
|
include: timeEntryIncludes,
|
||||||
|
orderBy: { dateStart: "desc" },
|
||||||
|
});
|
||||||
|
|
||||||
|
return data.map((e) => new TimeEntryController(e));
|
||||||
|
},
|
||||||
|
|
||||||
|
async countByMember(memberId: string): Promise<number> {
|
||||||
|
return prisma.timeEntry.count({ where: { memberId } });
|
||||||
|
},
|
||||||
|
|
||||||
|
async fetchByTicket(
|
||||||
|
serviceTicketId: number
|
||||||
|
): Promise<TimeEntryController[]> {
|
||||||
|
const data = await prisma.timeEntry.findMany({
|
||||||
|
where: { serviceTicketId },
|
||||||
|
include: timeEntryIncludes,
|
||||||
|
orderBy: { dateStart: "desc" },
|
||||||
|
});
|
||||||
|
|
||||||
|
return data.map((e) => new TimeEntryController(e));
|
||||||
|
},
|
||||||
|
|
||||||
|
async fetchByActivity(activityId: number): Promise<TimeEntryController[]> {
|
||||||
|
const data = await prisma.timeEntry.findMany({
|
||||||
|
where: { activityId },
|
||||||
|
include: timeEntryIncludes,
|
||||||
|
orderBy: { dateStart: "desc" },
|
||||||
|
});
|
||||||
|
|
||||||
|
return data.map((e) => new TimeEntryController(e));
|
||||||
|
},
|
||||||
|
|
||||||
|
async fetchByDateRange(
|
||||||
|
startDate: Date,
|
||||||
|
endDate: Date,
|
||||||
|
memberId?: string
|
||||||
|
): Promise<TimeEntryController[]> {
|
||||||
|
const data = await prisma.timeEntry.findMany({
|
||||||
|
where: {
|
||||||
|
dateStart: { gte: startDate, lte: endDate },
|
||||||
|
...(memberId ? { memberId } : {}),
|
||||||
|
},
|
||||||
|
include: timeEntryIncludes,
|
||||||
|
orderBy: { dateStart: "asc" },
|
||||||
|
});
|
||||||
|
|
||||||
|
return data.map((e) => new TimeEntryController(e));
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -1616,6 +1616,32 @@ export async function createScheduleEntry(
|
|||||||
: undefined;
|
: undefined;
|
||||||
const dateEnd = payload.endTime ? toCwDateTime(payload.endTime) : undefined;
|
const dateEnd = payload.endTime ? toCwDateTime(payload.endTime) : undefined;
|
||||||
|
|
||||||
|
// Find the currently open workflow activity (OpportunitySetup, OpportunityReview,
|
||||||
|
// or Revision) to use as the parent for this schedule entry.
|
||||||
|
let parentActivityCwId: number | null = null;
|
||||||
|
try {
|
||||||
|
const existingActivities = await activityCw.fetchByOpportunityDirect(
|
||||||
|
opportunity.cwOpportunityId,
|
||||||
|
);
|
||||||
|
for (const raw of existingActivities) {
|
||||||
|
if (raw.status?.id === 2) continue; // already closed
|
||||||
|
const optimaField = raw.customFields?.find(
|
||||||
|
(f: any) => f.id === OptimaType.FIELD_ID,
|
||||||
|
);
|
||||||
|
if (!optimaField?.value) continue;
|
||||||
|
if (optimaField.value === OptimaType.ScheduleEntry) continue; // skip other schedule entries
|
||||||
|
if (STAYS_OPEN_TYPES.has(optimaField.value as OptimaTypeValue)) {
|
||||||
|
parentActivityCwId = raw.id;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
// Non-fatal — schedule entry will be created without a parent
|
||||||
|
console.warn(
|
||||||
|
`[Workflow:ScheduleEntry] Could not resolve parent activity: ${err}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const activity = await ActivityController.create({
|
const activity = await ActivityController.create({
|
||||||
name: `[Schedule Entry] ${payload.activityTypeValue} — ${opportunity.name}`,
|
name: `[Schedule Entry] ${payload.activityTypeValue} — ${opportunity.name}`,
|
||||||
type: { id: 3 }, // HistoricEntry
|
type: { id: 3 }, // HistoricEntry
|
||||||
@@ -1627,12 +1653,8 @@ export async function createScheduleEntry(
|
|||||||
...(dateEnd ? { dateEnd } : {}),
|
...(dateEnd ? { dateEnd } : {}),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Set Optima_Type to Schedule Entry (stays open)
|
// Build custom fields: always Optima_Type, plus Parent_Activity when resolved
|
||||||
await activity.update([
|
const customFields: any[] = [
|
||||||
{
|
|
||||||
op: "replace",
|
|
||||||
path: "customFields",
|
|
||||||
value: [
|
|
||||||
{
|
{
|
||||||
id: OptimaType.FIELD_ID,
|
id: OptimaType.FIELD_ID,
|
||||||
caption: "Optima_Type",
|
caption: "Optima_Type",
|
||||||
@@ -1641,7 +1663,25 @@ export async function createScheduleEntry(
|
|||||||
numberOfDecimals: 0,
|
numberOfDecimals: 0,
|
||||||
value: OptimaType.ScheduleEntry,
|
value: OptimaType.ScheduleEntry,
|
||||||
},
|
},
|
||||||
],
|
];
|
||||||
|
|
||||||
|
if (parentActivityCwId != null) {
|
||||||
|
customFields.push({
|
||||||
|
id: PARENT_ACTIVITY_FIELD_ID,
|
||||||
|
caption: "Parent_Activity",
|
||||||
|
type: "Text",
|
||||||
|
entryMethod: "EntryField",
|
||||||
|
numberOfDecimals: 0,
|
||||||
|
value: String(parentActivityCwId),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set Optima_Type (+ Parent_Activity) on the new schedule entry
|
||||||
|
await activity.update([
|
||||||
|
{
|
||||||
|
op: "replace",
|
||||||
|
path: "customFields",
|
||||||
|
value: customFields,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|||||||
@@ -666,6 +666,7 @@ model Member {
|
|||||||
approvedOpportunities Opportunity[] @relation("OpportunityApprovedBy")
|
approvedOpportunities Opportunity[] @relation("OpportunityApprovedBy")
|
||||||
rejectedOpportunities Opportunity[] @relation("OpportunityRejectedBy")
|
rejectedOpportunities Opportunity[] @relation("OpportunityRejectedBy")
|
||||||
opportunityMembers OpportunityMember[] @relation("OpportunityMemberToMember")
|
opportunityMembers OpportunityMember[] @relation("OpportunityMemberToMember")
|
||||||
|
memberType MemberType? @relation(fields: [memberTypeRecId], references: [memberTypeRecId], onDelete: NoAction, onUpdate: NoAction)
|
||||||
|
|
||||||
@@map("Member")
|
@@map("Member")
|
||||||
@@schema("dbo")
|
@@schema("dbo")
|
||||||
@@ -1740,10 +1741,13 @@ model ActivityType {
|
|||||||
description String @map("Description") @db.NVarChar(50)
|
description String @map("Description") @db.NVarChar(50)
|
||||||
hoursMin Decimal? @map("Hours_Min") @db.Decimal(18, 2)
|
hoursMin Decimal? @map("Hours_Min") @db.Decimal(18, 2)
|
||||||
hoursMax Decimal? @map("Hours_Max") @db.Decimal(18, 2)
|
hoursMax Decimal? @map("Hours_Max") @db.Decimal(18, 2)
|
||||||
|
|
||||||
defaultFlag Boolean @map("Default_Flag")
|
defaultFlag Boolean @map("Default_Flag")
|
||||||
multiplierFlag Boolean @map("Multiplier_Flag")
|
multiplierFlag Boolean @map("Multiplier_Flag")
|
||||||
|
|
||||||
rate Decimal? @map("Rate") @db.Decimal(18, 2)
|
rate Decimal? @map("Rate") @db.Decimal(18, 2)
|
||||||
rateType String? @map("Rate_Type") @db.Char(1)
|
rateType String? @map("Rate_Type") @db.Char(1)
|
||||||
|
|
||||||
inactiveFlag Boolean @map("Inactive_Flag")
|
inactiveFlag Boolean @map("Inactive_Flag")
|
||||||
invoiceFlag Boolean @map("Invoice_Flag")
|
invoiceFlag Boolean @map("Invoice_Flag")
|
||||||
lastUpdate DateTime @map("Last_Update") @db.DateTime2
|
lastUpdate DateTime @map("Last_Update") @db.DateTime2
|
||||||
@@ -2069,45 +2073,63 @@ model Country {
|
|||||||
// =====================
|
// =====================
|
||||||
|
|
||||||
model SoActivity {
|
model SoActivity {
|
||||||
|
subject String? @map("Subject") @db.NVarChar(100)
|
||||||
|
|
||||||
soActivityRecId Int @id @map("SO_Activity_Recid")
|
soActivityRecId Int @id @map("SO_Activity_Recid")
|
||||||
opportunityRecId Int? @map("Opportunity_Recid")
|
opportunityRecId Int? @map("Opportunity_Recid")
|
||||||
|
companyRecId Int? @map("Company_RecID")
|
||||||
|
|
||||||
assignTo String @map("Assign_To") @db.NVarChar(15)
|
assignTo String @map("Assign_To") @db.NVarChar(15)
|
||||||
assignedBy String @map("Assigned_By") @db.NVarChar(15)
|
assignedBy String @map("Assigned_By") @db.NVarChar(15)
|
||||||
companyRecId Int? @map("Company_RecID")
|
|
||||||
soActivityTypeRecId Int? @map("SO_Activity_Type_RecID")
|
soActivityTypeRecId Int? @map("SO_Activity_Type_RecID")
|
||||||
subject String? @map("Subject") @db.NVarChar(100)
|
|
||||||
soReferenceRecId Int? @map("SO_Reference_RecID")
|
soReferenceRecId Int? @map("SO_Reference_RecID")
|
||||||
|
|
||||||
dateEntered DateTime @map("Date_Entered") @db.DateTime
|
dateEntered DateTime @map("Date_Entered") @db.DateTime
|
||||||
enteredBy String @map("Entered_By") @db.NVarChar(15)
|
enteredBy String @map("Entered_By") @db.NVarChar(15)
|
||||||
|
|
||||||
contactRecId Int? @map("Contact_RecID")
|
contactRecId Int? @map("Contact_RecID")
|
||||||
contactName String? @map("Contact_Name") @db.NVarChar(62)
|
contactName String? @map("Contact_Name") @db.NVarChar(62)
|
||||||
|
|
||||||
closeFlag Boolean @map("Close_Flag")
|
closeFlag Boolean @map("Close_Flag")
|
||||||
dateClosed DateTime? @map("Date_Closed") @db.DateTime
|
dateClosed DateTime? @map("Date_Closed") @db.DateTime
|
||||||
closedBy String? @map("Closed_By") @db.NVarChar(15)
|
closedBy String? @map("Closed_By") @db.NVarChar(15)
|
||||||
|
|
||||||
updatedBy String? @map("Updated_By") @db.NVarChar(15)
|
updatedBy String? @map("Updated_By") @db.NVarChar(15)
|
||||||
lastUpdate DateTime @map("Last_Update") @db.DateTime
|
lastUpdate DateTime @map("Last_Update") @db.DateTime
|
||||||
|
|
||||||
notifyCompleteFlag Boolean @map("Notify_Complete_Flag")
|
notifyCompleteFlag Boolean @map("Notify_Complete_Flag")
|
||||||
notificationSentFlag Boolean @map("Notification_Sent_Flag")
|
notificationSentFlag Boolean @map("Notification_Sent_Flag")
|
||||||
|
|
||||||
srServiceRecId Int? @map("SR_Service_RecID")
|
srServiceRecId Int? @map("SR_Service_RecID")
|
||||||
|
|
||||||
agrHeaderRecId Int? @map("AGR_Header_RecID")
|
agrHeaderRecId Int? @map("AGR_Header_RecID")
|
||||||
marketingCampaignRecId Int? @map("Marketing_Campaign_RecID")
|
marketingCampaignRecId Int? @map("Marketing_Campaign_RecID")
|
||||||
|
|
||||||
assignToRecId Int @map("assignto_recid")
|
assignToRecId Int @map("assignto_recid")
|
||||||
assignByRecId Int? @map("assignby_recid")
|
assignByRecId Int? @map("assignby_recid")
|
||||||
|
|
||||||
mobileGuid String @map("Mobile_Guid") @db.UniqueIdentifier
|
mobileGuid String @map("Mobile_Guid") @db.UniqueIdentifier
|
||||||
srLocationRecId Int? @map("SR_Location_RecID")
|
srLocationRecId Int? @map("SR_Location_RecID")
|
||||||
|
|
||||||
dateTimeStart DateTime? @map("Date_Time_Start") @db.DateTime
|
dateTimeStart DateTime? @map("Date_Time_Start") @db.DateTime
|
||||||
dateTimeEnd DateTime? @map("Date_Time_End") @db.DateTime
|
dateTimeEnd DateTime? @map("Date_Time_End") @db.DateTime
|
||||||
|
|
||||||
automated Boolean @map("Automated")
|
automated Boolean @map("Automated")
|
||||||
|
|
||||||
dateTimeStartUtc DateTime? @map("Date_Time_Start_UTC") @db.SmallDateTime
|
dateTimeStartUtc DateTime? @map("Date_Time_Start_UTC") @db.SmallDateTime
|
||||||
dateTimeEndUtc DateTime? @map("Date_Time_End_UTC") @db.SmallDateTime
|
dateTimeEndUtc DateTime? @map("Date_Time_End_UTC") @db.SmallDateTime
|
||||||
dateEnteredUtc DateTime @map("Date_Entered_UTC") @db.DateTime
|
dateEnteredUtc DateTime @map("Date_Entered_UTC") @db.DateTime
|
||||||
lastUpdatedUTC DateTime @map("Last_Update_UTC") @db.DateTime
|
lastUpdatedUTC DateTime @map("Last_Update_UTC") @db.DateTime
|
||||||
dateClosedUtc DateTime? @map("Date_Closed_UTC") @db.DateTime
|
dateClosedUtc DateTime? @map("Date_Closed_UTC") @db.DateTime
|
||||||
|
|
||||||
soActStatusRecId Int @map("so_act_status_recid")
|
soActStatusRecId Int @map("so_act_status_recid")
|
||||||
currencyRecId Int @map("Currency_RecID")
|
currencyRecId Int @map("Currency_RecID")
|
||||||
|
|
||||||
id String? @map("Id") @db.UniqueIdentifier
|
id String? @map("Id") @db.UniqueIdentifier
|
||||||
|
|
||||||
opportunity Opportunity? @relation(fields: [opportunityRecId], references: [opportunityRecId], onDelete: NoAction, onUpdate: NoAction)
|
opportunity Opportunity? @relation(fields: [opportunityRecId], references: [opportunityRecId], onDelete: NoAction, onUpdate: NoAction)
|
||||||
|
notes SoActivityNotes?
|
||||||
|
|
||||||
@@map("SO_Activity")
|
@@map("SO_Activity")
|
||||||
@@schema("dbo")
|
@@schema("dbo")
|
||||||
@@ -2303,6 +2325,7 @@ model ScheduleType {
|
|||||||
id String @map("Id") @db.UniqueIdentifier
|
id String @map("Id") @db.UniqueIdentifier
|
||||||
|
|
||||||
schedules Schedule[]
|
schedules Schedule[]
|
||||||
|
teChargeCode TeChargeCode? @relation(fields: [teChargeCodeRecId], references: [teChargeCodeRecId], onDelete: NoAction, onUpdate: NoAction)
|
||||||
|
|
||||||
@@map("Schedule_Type")
|
@@map("Schedule_Type")
|
||||||
@@schema("dbo")
|
@@schema("dbo")
|
||||||
@@ -2398,3 +2421,246 @@ model ScheduleDetail {
|
|||||||
@@map("Schedule_Detail")
|
@@map("Schedule_Detail")
|
||||||
@@schema("dbo")
|
@@schema("dbo")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// =====================
|
||||||
|
// TIME
|
||||||
|
// =====================
|
||||||
|
|
||||||
|
model TimeEntry {
|
||||||
|
companyRecId Int @map("Company_RecID")
|
||||||
|
timeRecId Int @map("Time_RecID")
|
||||||
|
enteredBy String? @map("Entered_By") @db.NVarChar(15)
|
||||||
|
memberId String? @map("Member_ID") @db.NVarChar(15)
|
||||||
|
|
||||||
|
dateStart DateTime? @map("Date_Start") @db.DateTime
|
||||||
|
timeStart DateTime? @map("Time_Start") @db.DateTime
|
||||||
|
timeEnd DateTime? @map("Time_End") @db.DateTime
|
||||||
|
hourlyRate Float? @map("Hourly_Rate") @db.SmallMoney
|
||||||
|
hoursBill Decimal @map("Hours_Bill") @db.Decimal(18, 2)
|
||||||
|
|
||||||
|
invoiceFlag Boolean @map("Invoice_Flag")
|
||||||
|
|
||||||
|
lastUpdate DateTime? @map("Last_Update") @db.DateTime
|
||||||
|
updatedBy String? @map("Updated_By") @db.NVarChar(15)
|
||||||
|
|
||||||
|
pmProjectRecId Int? @map("PM_Project_RecID")
|
||||||
|
|
||||||
|
hoursActual Decimal @map("Hours_Actual") @db.Decimal(18, 2)
|
||||||
|
billableFlag Boolean @map("Billable_Flag")
|
||||||
|
billingLogRecId Int? @map("Billing_Log_RecID")
|
||||||
|
|
||||||
|
srServiceRecId Int? @map("SR_Service_RecID")
|
||||||
|
|
||||||
|
activityTypeRecId Int? @map("Activity_Type_RecID")
|
||||||
|
activityClassRecId Int? @map("Activity_Class_RecID")
|
||||||
|
|
||||||
|
teStatusId Int @map("TE_Status_ID") @db.SmallInt
|
||||||
|
timeSheetRecId Int? @map("Time_Sheet_RecID")
|
||||||
|
teChargeCodeRecId Int? @map("TE_Charge_Code_RecID")
|
||||||
|
|
||||||
|
billingUnitRecId Int @map("Billing_Unit_RecID")
|
||||||
|
ownerLevelRecId Int @map("Owner_Level_RecID")
|
||||||
|
|
||||||
|
memberRecId Int? @map("Member_RecID")
|
||||||
|
|
||||||
|
hoursInvoiced Decimal? @map("Hours_Invoiced") @db.Decimal(18, 2)
|
||||||
|
adjustment Decimal @map("Adjustment") @db.Decimal(18, 2)
|
||||||
|
|
||||||
|
memberTypeRecId Int? @map("Member_Type_RecID")
|
||||||
|
|
||||||
|
agrAmount Decimal @map("Agr_Amount") @db.Decimal(18, 2)
|
||||||
|
agrHeaderRecId Int? @map("Agr_Header_RecID")
|
||||||
|
agrAdjustment Decimal? @map("Agr_Adjustment") @db.Decimal(18, 2)
|
||||||
|
agrHours Decimal? @map("Agr_Hours") @db.Decimal(18, 2)
|
||||||
|
agrMonth Int? @map("Agr_Month") @db.SmallInt
|
||||||
|
agrYear Int? @map("Agr_Year") @db.SmallInt
|
||||||
|
|
||||||
|
standardRate Decimal? @map("Standard_Rate") @db.Decimal(18, 2)
|
||||||
|
effectiveRate Decimal? @map("Effective_Rate") @db.Decimal(18, 2)
|
||||||
|
|
||||||
|
hoursDeduct Decimal? @map("Hours_Deduct") @db.Decimal(18, 2)
|
||||||
|
|
||||||
|
contactRecId Int? @map("Contact_RecID")
|
||||||
|
|
||||||
|
soActivityRecId Int? @map("SO_Activity_RecID")
|
||||||
|
mobileGuid String @map("Mobile_GUID") @db.UniqueIdentifier
|
||||||
|
billingSr Int? @map("billing_sr")
|
||||||
|
|
||||||
|
signatureRecId Int? @map("Signature_RecID")
|
||||||
|
signatureHours Decimal? @map("Signature_Hours") @db.Decimal(18, 2)
|
||||||
|
|
||||||
|
exchangeHref String? @map("exchange_href") @db.NVarChar(300)
|
||||||
|
teProblemFlag Boolean @map("TE_Problem_Flag")
|
||||||
|
teResolutionFlag Boolean @map("TE_Resolution_Flag")
|
||||||
|
teInternalAnalysisFlag Boolean @map("TE_InternalAnalysis_Flag")
|
||||||
|
|
||||||
|
documentFlag Boolean @map("Document_Flag")
|
||||||
|
|
||||||
|
dateFormat Int? @map("Date_Format")
|
||||||
|
|
||||||
|
dbTimestamp Bytes @map("DB_Timestamp") @db.VarBinary(8)
|
||||||
|
timeStartUtc DateTime? @map("Time_Start_UTC") @db.DateTime
|
||||||
|
timeEndUtc DateTime? @map("Time_End_UTC") @db.DateTime
|
||||||
|
lastUpdateUtc DateTime? @map("Last_Update_UTC") @db.DateTime
|
||||||
|
dateEnteredUtc DateTime @map("Date_Entered_UTC") @db.DateTime
|
||||||
|
|
||||||
|
overageRate Float? @map("Overage_Rate") @db.SmallMoney
|
||||||
|
|
||||||
|
extendedInvoiceAmount Decimal? @map("Extended_Invoice_Amount") @db.Decimal(31, 6)
|
||||||
|
extendedBillAmount Decimal? @map("Extended_Bill_Amount") @db.Decimal(31, 6)
|
||||||
|
|
||||||
|
notificationHistory String @map("Notification_History") @db.VarChar(4000)
|
||||||
|
mergedFlag Boolean @map("Merged_Flag")
|
||||||
|
|
||||||
|
internalNote String? @map("Internal_Note") @db.NVarChar(Max)
|
||||||
|
reference String? @map("Reference") @db.NVarChar(100)
|
||||||
|
|
||||||
|
originalAuthor String? @map("Original_Author") @db.NVarChar(150)
|
||||||
|
|
||||||
|
costPerHour String @map("Cost_Per_Hour") @db.NVarChar(2000)
|
||||||
|
overrideFlag Boolean @map("Override_Flag")
|
||||||
|
issueFlag Boolean @map("Issue_Flag")
|
||||||
|
|
||||||
|
notes String? @map("Notes") @db.NVarChar(4000)
|
||||||
|
notesMarkdown String? @map("Notes_Markdown") @db.NVarChar(Max)
|
||||||
|
|
||||||
|
chargeToRecId Int? @map("Charge_To_RecID")
|
||||||
|
chargeToType String? @map("Charge_To_Type") @db.NVarChar(13)
|
||||||
|
|
||||||
|
teChargeCode TeChargeCode? @relation(fields: [teChargeCodeRecId], references: [teChargeCodeRecId], onDelete: NoAction, onUpdate: NoAction)
|
||||||
|
memberType MemberType? @relation(fields: [memberTypeRecId], references: [memberTypeRecId], onDelete: NoAction, onUpdate: NoAction)
|
||||||
|
|
||||||
|
@@id([companyRecId, timeRecId])
|
||||||
|
@@map("Time_Entry")
|
||||||
|
@@schema("dbo")
|
||||||
|
}
|
||||||
|
|
||||||
|
model SoActivityType {
|
||||||
|
soActivityTypeRecId Int @id @map("SO_Activity_Type_RecID")
|
||||||
|
soActivityTypeId String? @map("SO_Activity_Type_ID") @db.NVarChar(15)
|
||||||
|
|
||||||
|
description String? @map("Description") @db.NVarChar(50)
|
||||||
|
|
||||||
|
historyFlag Boolean @map("History_Flag")
|
||||||
|
|
||||||
|
updatedBy String @map("Updated_By") @db.NVarChar(15)
|
||||||
|
cleanUpFlag Boolean @map("CleanUp_Flag")
|
||||||
|
defaultFlag Boolean @map("Default_Flag")
|
||||||
|
importFlag Boolean @map("Import_Flag")
|
||||||
|
emailFlag Boolean @map("email_flag")
|
||||||
|
memoFlag Boolean? @map("Memo_Flag")
|
||||||
|
pointsValue Int? @map("Points_Value")
|
||||||
|
inactiveFlag Boolean? @map("Inactive_Flag")
|
||||||
|
lastUpdateUtc DateTime @map("Last_Update_UTC") @db.DateTime2
|
||||||
|
dateEnteredUtc DateTime @map("Date_Entered_UTC") @db.DateTime2
|
||||||
|
enteredBy String @map("Entered_By") @db.NVarChar(15)
|
||||||
|
id String @map("Id") @db.UniqueIdentifier
|
||||||
|
|
||||||
|
@@map("SO_Activity_Type")
|
||||||
|
@@schema("dbo")
|
||||||
|
}
|
||||||
|
|
||||||
|
model SoActStatus {
|
||||||
|
soActStatusRecId Int @id @map("SO_Act_Status_RecID")
|
||||||
|
description String? @map("Description") @db.NVarChar(30)
|
||||||
|
|
||||||
|
defaultFlag Boolean @map("Default_Flag")
|
||||||
|
closedFlag Boolean @map("Closed_Flag")
|
||||||
|
inactiveFlag Boolean @map("Inactive_Flag")
|
||||||
|
spawnFollowupFlag Boolean @map("spawn_followup_flag")
|
||||||
|
|
||||||
|
lastUpdate DateTime @map("Last_Update") @db.DateTime2
|
||||||
|
lastUpdateUtc DateTime @map("Last_Update_UTC") @db.DateTime2
|
||||||
|
dateEnteredUtc DateTime @map("Date_Entered_UTC") @db.DateTime2
|
||||||
|
|
||||||
|
updatedBy String? @map("Updated_By") @db.NVarChar(15)
|
||||||
|
enteredBy String @map("Entered_By") @db.NVarChar(15)
|
||||||
|
|
||||||
|
id String @map("Id") @db.UniqueIdentifier
|
||||||
|
|
||||||
|
@@map("SO_Act_Status")
|
||||||
|
@@schema("dbo")
|
||||||
|
}
|
||||||
|
|
||||||
|
model SoActivityNotes {
|
||||||
|
soActivityNotesRecId Int @id @map("SO_Activity_Notes_RecID")
|
||||||
|
soActivityRecId Int @unique @map("SO_Activity_RecID")
|
||||||
|
notes String @map("Notes") @db.NVarChar(Max)
|
||||||
|
internalAnalysisFlag Boolean @map("Internal_Analysis_Flag")
|
||||||
|
dateCreatedUtc DateTime @map("Date_Created_UTC") @db.DateTime2
|
||||||
|
enteredBy String @map("Entered_By") @db.NVarChar(15)
|
||||||
|
lastUpdateUtc DateTime @map("Last_Update_UTC") @db.DateTime2
|
||||||
|
updatedBy String @map("Updated_By") @db.NVarChar(15)
|
||||||
|
|
||||||
|
soActivity SoActivity @relation(fields: [soActivityRecId], references: [soActivityRecId], onDelete: NoAction, onUpdate: NoAction)
|
||||||
|
|
||||||
|
@@map("SO_Activity_Notes")
|
||||||
|
@@schema("dbo")
|
||||||
|
}
|
||||||
|
|
||||||
|
// =====================
|
||||||
|
// TIME ENTRY LOOKUPS
|
||||||
|
// =====================
|
||||||
|
|
||||||
|
model TeStatus {
|
||||||
|
teStatusRecId Int @id @map("TE_Status_RecID")
|
||||||
|
teStatusId Int @map("TE_Status_ID") @db.SmallInt
|
||||||
|
description String? @map("Description") @db.NVarChar(50)
|
||||||
|
action String? @map("Action") @db.NVarChar(50)
|
||||||
|
lastUpdatedUtc DateTime @map("Last_Updated_UTC") @db.DateTime2
|
||||||
|
localeKeyRecId Int? @map("Locale_Key_RecID")
|
||||||
|
|
||||||
|
@@map("TE_Status")
|
||||||
|
@@schema("dbo")
|
||||||
|
}
|
||||||
|
|
||||||
|
model TeChargeCode {
|
||||||
|
teChargeCodeRecId Int @id @map("TE_Charge_Code_RecID")
|
||||||
|
|
||||||
|
description String? @map("Description") @db.NVarChar(50)
|
||||||
|
|
||||||
|
companyRecId Int? @map("Company_RecID")
|
||||||
|
ownerLevelRecId Int? @map("Owner_Level_RecID")
|
||||||
|
billingUnitRecId Int? @map("Billing_Unit_RecID")
|
||||||
|
|
||||||
|
activityClassRecId Int? @map("Activity_Class_RecID")
|
||||||
|
activityTypeRecId Int? @map("Activity_Type_RecID")
|
||||||
|
|
||||||
|
expenseFlag Boolean @map("Expense_Flag")
|
||||||
|
timeFlag Boolean @map("Time_Flag")
|
||||||
|
|
||||||
|
updatedBy String? @map("Updated_By") @db.NVarChar(15)
|
||||||
|
lastUpdate DateTime @map("Last_Update") @db.DateTime2
|
||||||
|
billableFlag Boolean @map("Billable_Flag")
|
||||||
|
exTypeFlag Boolean @map("EX_Type_Flag")
|
||||||
|
invoiceFlag Boolean? @map("Invoice_Flag")
|
||||||
|
integrationXref String? @map("Integration_Xref") @db.NVarChar(50)
|
||||||
|
lastUpdateUtc DateTime @map("Last_Update_UTC") @db.DateTime2
|
||||||
|
enteredBy String @map("Entered_By") @db.NVarChar(15)
|
||||||
|
dateEnteredUtc DateTime @map("Date_Entered_UTC") @db.DateTime2
|
||||||
|
id String @map("Id") @db.UniqueIdentifier
|
||||||
|
|
||||||
|
scheduleTypes ScheduleType[]
|
||||||
|
timeEntries TimeEntry[]
|
||||||
|
|
||||||
|
@@map("TE_Charge_Code")
|
||||||
|
@@schema("dbo")
|
||||||
|
}
|
||||||
|
|
||||||
|
model MemberType {
|
||||||
|
memberTypeRecId Int @id @map("Member_Type_RecID")
|
||||||
|
description String? @map("Description") @db.NVarChar(30)
|
||||||
|
inactiveFlag Boolean @map("Inactive_Flag")
|
||||||
|
updatedBy String? @map("Updated_By") @db.NVarChar(15)
|
||||||
|
lastUpdate DateTime @map("Last_Update") @db.DateTime2
|
||||||
|
lastUpdateUtc DateTime @map("Last_Update_UTC") @db.DateTime2
|
||||||
|
enteredBy String @map("Entered_By") @db.NVarChar(15)
|
||||||
|
dateEnteredUtc DateTime @map("Date_Entered_UTC") @db.DateTime2
|
||||||
|
id String @map("Id") @db.UniqueIdentifier
|
||||||
|
|
||||||
|
members Member[]
|
||||||
|
timeEntries TimeEntry[]
|
||||||
|
|
||||||
|
@@map("Member_Type")
|
||||||
|
@@schema("dbo")
|
||||||
|
}
|
||||||
|
|||||||
@@ -31,6 +31,16 @@ export { scheduleTypeTranslation } from "./translations/schedule-type";
|
|||||||
export { scheduleSpanTranslation } from "./translations/schedule-span";
|
export { scheduleSpanTranslation } from "./translations/schedule-span";
|
||||||
export { scheduleTranslation } from "./translations/schedule";
|
export { scheduleTranslation } from "./translations/schedule";
|
||||||
export { taxCodeTranslation } from "./translations/tax-code";
|
export { taxCodeTranslation } from "./translations/tax-code";
|
||||||
|
export { timeEntryTranslation } from "./translations/time-entry";
|
||||||
|
export { timeEntryStatusTranslation } from "./translations/time-entry-status";
|
||||||
|
export { timeEntryChargeCodeTranslation } from "./translations/time-entry-charge-code";
|
||||||
|
export { timeActivityClassTranslation } from "./translations/time-activity-class";
|
||||||
|
export { timeActivityTypeTranslation } from "./translations/time-activity-type";
|
||||||
|
export { activityTypeTranslation } from "./translations/activity-type";
|
||||||
|
export { activityStatusTranslation } from "./translations/activity-status";
|
||||||
|
export { activityTranslation } from "./translations/activity";
|
||||||
|
export { activityNotesTranslation } from "./translations/activity-notes";
|
||||||
|
export { cwMemberTypeTranslation } from "./translations/cw-member-type";
|
||||||
|
|
||||||
// Context type exports
|
// Context type exports
|
||||||
export type { TranslationContext } from "./translations/context";
|
export type { TranslationContext } from "./translations/context";
|
||||||
|
|||||||
@@ -37,6 +37,12 @@ import {
|
|||||||
scheduleTypeTranslation,
|
scheduleTypeTranslation,
|
||||||
scheduleSpanTranslation,
|
scheduleSpanTranslation,
|
||||||
scheduleTranslation,
|
scheduleTranslation,
|
||||||
|
taxCodeTranslation,
|
||||||
|
timeEntryTranslation,
|
||||||
|
activityTypeTranslation,
|
||||||
|
activityStatusTranslation,
|
||||||
|
activityTranslation,
|
||||||
|
activityNotesTranslation,
|
||||||
userTranslation,
|
userTranslation,
|
||||||
warehouseBinTranslation,
|
warehouseBinTranslation,
|
||||||
type TranslationContext,
|
type TranslationContext,
|
||||||
@@ -203,6 +209,9 @@ const refreshContextFromApi = async (
|
|||||||
context.scheduleStatusIds.clear();
|
context.scheduleStatusIds.clear();
|
||||||
context.scheduleTypeIds.clear();
|
context.scheduleTypeIds.clear();
|
||||||
context.scheduleSpanIds.clear();
|
context.scheduleSpanIds.clear();
|
||||||
|
context.activityTypeIds.clear();
|
||||||
|
context.activityStatusIds.clear();
|
||||||
|
context.activityIds.clear();
|
||||||
|
|
||||||
const [
|
const [
|
||||||
users,
|
users,
|
||||||
@@ -215,6 +224,9 @@ const refreshContextFromApi = async (
|
|||||||
scheduleStatuses,
|
scheduleStatuses,
|
||||||
scheduleTypes,
|
scheduleTypes,
|
||||||
scheduleSpans,
|
scheduleSpans,
|
||||||
|
activityTypes,
|
||||||
|
activityStatuses,
|
||||||
|
activities,
|
||||||
] = await Promise.all([
|
] = await Promise.all([
|
||||||
apiPrisma.user.findMany({
|
apiPrisma.user.findMany({
|
||||||
select: {
|
select: {
|
||||||
@@ -269,6 +281,21 @@ const refreshContextFromApi = async (
|
|||||||
id: true,
|
id: true,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
apiPrisma.activityType.findMany({
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
apiPrisma.activityStatus.findMany({
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
apiPrisma.activity.findMany({
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
},
|
||||||
|
}),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const defaultOpportunityType = await apiPrisma.opportunityType.findFirst({
|
const defaultOpportunityType = await apiPrisma.opportunityType.findFirst({
|
||||||
@@ -346,6 +373,18 @@ const refreshContextFromApi = async (
|
|||||||
context.scheduleSpanIds.add(span.id);
|
context.scheduleSpanIds.add(span.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const activityType of activityTypes) {
|
||||||
|
context.activityTypeIds.add(activityType.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const activityStatus of activityStatuses) {
|
||||||
|
context.activityStatusIds.add(activityStatus.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const activity of activities) {
|
||||||
|
context.activityIds.add(activity.id);
|
||||||
|
}
|
||||||
|
|
||||||
context.defaultOpportunityTypeId = defaultOpportunityType?.id ?? null;
|
context.defaultOpportunityTypeId = defaultOpportunityType?.id ?? null;
|
||||||
|
|
||||||
// Optional context fed from env-provided maps.
|
// Optional context fed from env-provided maps.
|
||||||
@@ -813,6 +852,41 @@ const getConfigForTable = (table: string): SyncTableConfig | null => {
|
|||||||
uniqueField: "id",
|
uniqueField: "id",
|
||||||
lastUpdatedField: "lastUpdateUtc",
|
lastUpdatedField: "lastUpdateUtc",
|
||||||
},
|
},
|
||||||
|
timeEntry: {
|
||||||
|
sourceModel: "timeEntry",
|
||||||
|
targetModel: "timeEntry",
|
||||||
|
translation: timeEntryTranslation as unknown as AnyTranslation,
|
||||||
|
uniqueField: "id",
|
||||||
|
lastUpdatedField: "lastUpdateUtc",
|
||||||
|
},
|
||||||
|
soActivityType: {
|
||||||
|
sourceModel: "soActivityType",
|
||||||
|
targetModel: "activityType",
|
||||||
|
translation: activityTypeTranslation as unknown as AnyTranslation,
|
||||||
|
uniqueField: "id",
|
||||||
|
lastUpdatedField: "lastUpdateUtc",
|
||||||
|
},
|
||||||
|
soActStatus: {
|
||||||
|
sourceModel: "soActStatus",
|
||||||
|
targetModel: "activityStatus",
|
||||||
|
translation: activityStatusTranslation as unknown as AnyTranslation,
|
||||||
|
uniqueField: "id",
|
||||||
|
lastUpdatedField: "lastUpdateUtc",
|
||||||
|
},
|
||||||
|
soActivity: {
|
||||||
|
sourceModel: "soActivity",
|
||||||
|
targetModel: "activity",
|
||||||
|
translation: activityTranslation as unknown as AnyTranslation,
|
||||||
|
uniqueField: "id",
|
||||||
|
lastUpdatedField: "lastUpdatedUTC",
|
||||||
|
},
|
||||||
|
soActivityNotes: {
|
||||||
|
sourceModel: "soActivityNotes",
|
||||||
|
targetModel: "activityNotes",
|
||||||
|
translation: activityNotesTranslation as unknown as AnyTranslation,
|
||||||
|
uniqueField: "id",
|
||||||
|
lastUpdatedField: "lastUpdateUtc",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
return configMap[table] ?? null;
|
return configMap[table] ?? null;
|
||||||
@@ -984,8 +1058,7 @@ export async function syncTableUpdates(
|
|||||||
|
|
||||||
if (failed > sampleErrorsPrinted) {
|
if (failed > sampleErrorsPrinted) {
|
||||||
console.error(
|
console.error(
|
||||||
`${config.sourceModel}: suppressed ${
|
`${config.sourceModel}: suppressed ${failed - sampleErrorsPrinted
|
||||||
failed - sampleErrorsPrinted
|
|
||||||
} additional row errors`
|
} additional row errors`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+174
-17
@@ -39,6 +39,16 @@ import {
|
|||||||
scheduleSpanTranslation,
|
scheduleSpanTranslation,
|
||||||
scheduleTranslation,
|
scheduleTranslation,
|
||||||
taxCodeTranslation,
|
taxCodeTranslation,
|
||||||
|
timeEntryTranslation,
|
||||||
|
timeEntryStatusTranslation,
|
||||||
|
timeEntryChargeCodeTranslation,
|
||||||
|
timeActivityClassTranslation,
|
||||||
|
timeActivityTypeTranslation,
|
||||||
|
activityTypeTranslation,
|
||||||
|
activityStatusTranslation,
|
||||||
|
activityTranslation,
|
||||||
|
activityNotesTranslation,
|
||||||
|
cwMemberTypeTranslation,
|
||||||
userTranslation,
|
userTranslation,
|
||||||
warehouseBinTranslation,
|
warehouseBinTranslation,
|
||||||
type TranslationContext,
|
type TranslationContext,
|
||||||
@@ -346,6 +356,11 @@ const refreshContextFromApi = async (
|
|||||||
context.scheduleTypeIds.clear();
|
context.scheduleTypeIds.clear();
|
||||||
context.scheduleSpanIds.clear();
|
context.scheduleSpanIds.clear();
|
||||||
context.taxCodeIds.clear();
|
context.taxCodeIds.clear();
|
||||||
|
context.activityTypeIds.clear();
|
||||||
|
context.activityStatusIds.clear();
|
||||||
|
context.activityIds.clear();
|
||||||
|
context.timeEntryChargeCodeIds.clear();
|
||||||
|
context.timeEntryStatusIdByTeStatusId.clear();
|
||||||
|
|
||||||
const [
|
const [
|
||||||
users,
|
users,
|
||||||
@@ -363,6 +378,11 @@ const refreshContextFromApi = async (
|
|||||||
scheduleTypes,
|
scheduleTypes,
|
||||||
scheduleSpans,
|
scheduleSpans,
|
||||||
taxCodes,
|
taxCodes,
|
||||||
|
activityTypes,
|
||||||
|
activityStatuses,
|
||||||
|
activities,
|
||||||
|
timeEntryChargeCodes,
|
||||||
|
timeEntryStatuses,
|
||||||
] = await Promise.all([
|
] = await Promise.all([
|
||||||
apiPrisma.user.findMany({
|
apiPrisma.user.findMany({
|
||||||
select: {
|
select: {
|
||||||
@@ -442,6 +462,32 @@ const refreshContextFromApi = async (
|
|||||||
id: true,
|
id: true,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
apiPrisma.activityType.findMany({
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
apiPrisma.activityStatus.findMany({
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
apiPrisma.activity.findMany({
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
apiPrisma.timeEntryChargeCode.findMany({
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
apiPrisma.timeEntryStatus.findMany({
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
statusId: true,
|
||||||
|
},
|
||||||
|
}),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const defaultOpportunityType = await apiPrisma.opportunityType.findFirst({
|
const defaultOpportunityType = await apiPrisma.opportunityType.findFirst({
|
||||||
@@ -539,6 +585,26 @@ const refreshContextFromApi = async (
|
|||||||
context.taxCodeIds.add(taxCode.id);
|
context.taxCodeIds.add(taxCode.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const activityType of activityTypes) {
|
||||||
|
context.activityTypeIds.add(activityType.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const activityStatus of activityStatuses) {
|
||||||
|
context.activityStatusIds.add(activityStatus.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const activity of activities) {
|
||||||
|
context.activityIds.add(activity.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const chargeCode of timeEntryChargeCodes) {
|
||||||
|
context.timeEntryChargeCodeIds.add(chargeCode.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const status of timeEntryStatuses) {
|
||||||
|
context.timeEntryStatusIdByTeStatusId.set(status.statusId, status.id);
|
||||||
|
}
|
||||||
|
|
||||||
context.defaultOpportunityTypeId = defaultOpportunityType?.id ?? null;
|
context.defaultOpportunityTypeId = defaultOpportunityType?.id ?? null;
|
||||||
|
|
||||||
// Optional context fed from env-provided maps.
|
// Optional context fed from env-provided maps.
|
||||||
@@ -1073,8 +1139,7 @@ const reconcileStepDeletes = async (
|
|||||||
const message =
|
const message =
|
||||||
error instanceof Error ? error.message : "Unknown delete error";
|
error instanceof Error ? error.message : "Unknown delete error";
|
||||||
console.error(
|
console.error(
|
||||||
`Delete reconcile failed in ${step.name} for ${
|
`Delete reconcile failed in ${step.name} for ${step.uniqueField
|
||||||
step.uniqueField
|
|
||||||
}=${formatValue(value)}:`,
|
}=${formatValue(value)}:`,
|
||||||
message
|
message
|
||||||
);
|
);
|
||||||
@@ -1085,8 +1150,7 @@ const reconcileStepDeletes = async (
|
|||||||
|
|
||||||
if (failed > sampleErrorsPrinted) {
|
if (failed > sampleErrorsPrinted) {
|
||||||
console.error(
|
console.error(
|
||||||
`${step.name}: suppressed ${
|
`${step.name}: suppressed ${failed - sampleErrorsPrinted
|
||||||
failed - sampleErrorsPrinted
|
|
||||||
} additional delete errors`
|
} additional delete errors`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1129,10 +1193,8 @@ const logAllSmartSyncDifferences = (
|
|||||||
? diff.apiUpdatedAt.toISOString()
|
? diff.apiUpdatedAt.toISOString()
|
||||||
: "null";
|
: "null";
|
||||||
console.log(
|
console.log(
|
||||||
` [diff] sourceModel=${step.sourceModel} targetModel=${
|
` [diff] sourceModel=${step.sourceModel} targetModel=${step.targetModel
|
||||||
step.targetModel
|
} id=${diff.sourceId} reason=${diff.reason
|
||||||
} id=${diff.sourceId} reason=${
|
|
||||||
diff.reason
|
|
||||||
} cwUpdatedAt=${diff.cwUpdatedAt.toISOString()} apiUpdatedAt=${apiUpdated}`
|
} cwUpdatedAt=${diff.cwUpdatedAt.toISOString()} apiUpdatedAt=${apiUpdated}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1393,8 +1455,7 @@ const syncStep = async (
|
|||||||
|
|
||||||
if (failed > sampleErrorsPrinted) {
|
if (failed > sampleErrorsPrinted) {
|
||||||
console.error(
|
console.error(
|
||||||
`${step.name}: suppressed ${
|
`${step.name}: suppressed ${failed - sampleErrorsPrinted
|
||||||
failed - sampleErrorsPrinted
|
|
||||||
} additional row errors`
|
} additional row errors`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1495,6 +1556,15 @@ export const executeFullDalpuriSync = async (options?: {
|
|||||||
const isTimedOut = () => Date.now() - syncStartTime > timeoutMs;
|
const isTimedOut = () => Date.now() - syncStartTime > timeoutMs;
|
||||||
|
|
||||||
const steps: Step[] = [
|
const steps: Step[] = [
|
||||||
|
{
|
||||||
|
name: "CW Member Types",
|
||||||
|
sourceModel: "memberType",
|
||||||
|
targetModel: "cwMemberType",
|
||||||
|
translation: cwMemberTypeTranslation as unknown as AnyTranslation,
|
||||||
|
uniqueField: "id",
|
||||||
|
sourceIdField: "memberTypeRecId",
|
||||||
|
sourceUpdatedField: "lastUpdateUtc",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "CW Members",
|
name: "CW Members",
|
||||||
sourceModel: "member",
|
sourceModel: "member",
|
||||||
@@ -1829,6 +1899,87 @@ export const executeFullDalpuriSync = async (options?: {
|
|||||||
sourceIdField: "scheduleRecId",
|
sourceIdField: "scheduleRecId",
|
||||||
sourceUpdatedField: "lastUpdateUtc",
|
sourceUpdatedField: "lastUpdateUtc",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "Time Entry Statuses",
|
||||||
|
sourceModel: "teStatus",
|
||||||
|
targetModel: "timeEntryStatus",
|
||||||
|
translation: timeEntryStatusTranslation as unknown as AnyTranslation,
|
||||||
|
uniqueField: "id",
|
||||||
|
sourceIdField: "teStatusRecId",
|
||||||
|
sourceUpdatedField: "lastUpdatedUtc",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Time Entry Charge Codes",
|
||||||
|
sourceModel: "teChargeCode",
|
||||||
|
targetModel: "timeEntryChargeCode",
|
||||||
|
translation: timeEntryChargeCodeTranslation as unknown as AnyTranslation,
|
||||||
|
uniqueField: "id",
|
||||||
|
sourceIdField: "teChargeCodeRecId",
|
||||||
|
sourceUpdatedField: "lastUpdateUtc",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Time Activity Classes",
|
||||||
|
sourceModel: "activityClass",
|
||||||
|
targetModel: "timeActivityClass",
|
||||||
|
translation: timeActivityClassTranslation as unknown as AnyTranslation,
|
||||||
|
uniqueField: "id",
|
||||||
|
sourceIdField: "activityClassRecId",
|
||||||
|
sourceUpdatedField: "lastUpdatedUtc",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Time Activity Types",
|
||||||
|
sourceModel: "activityType",
|
||||||
|
targetModel: "timeActivityType",
|
||||||
|
translation: timeActivityTypeTranslation as unknown as AnyTranslation,
|
||||||
|
uniqueField: "id",
|
||||||
|
sourceIdField: "activityTypeRecId",
|
||||||
|
sourceUpdatedField: "lastUpdatedUtc",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Time Entries",
|
||||||
|
sourceModel: "timeEntry",
|
||||||
|
targetModel: "timeEntry",
|
||||||
|
translation: timeEntryTranslation as unknown as AnyTranslation,
|
||||||
|
uniqueField: "id",
|
||||||
|
sourceIdField: "timeRecId",
|
||||||
|
sourceUpdatedField: "lastUpdateUtc",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Activity Types",
|
||||||
|
sourceModel: "soActivityType",
|
||||||
|
targetModel: "activityType",
|
||||||
|
translation: activityTypeTranslation as unknown as AnyTranslation,
|
||||||
|
uniqueField: "id",
|
||||||
|
sourceIdField: "soActivityTypeRecId",
|
||||||
|
sourceUpdatedField: "lastUpdateUtc",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Activity Statuses",
|
||||||
|
sourceModel: "soActStatus",
|
||||||
|
targetModel: "activityStatus",
|
||||||
|
translation: activityStatusTranslation as unknown as AnyTranslation,
|
||||||
|
uniqueField: "id",
|
||||||
|
sourceIdField: "soActStatusRecId",
|
||||||
|
sourceUpdatedField: "lastUpdateUtc",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Activities",
|
||||||
|
sourceModel: "soActivity",
|
||||||
|
targetModel: "activity",
|
||||||
|
translation: activityTranslation as unknown as AnyTranslation,
|
||||||
|
uniqueField: "id",
|
||||||
|
sourceIdField: "soActivityRecId",
|
||||||
|
sourceUpdatedField: "lastUpdatedUTC",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Activity Notes",
|
||||||
|
sourceModel: "soActivityNotes",
|
||||||
|
targetModel: "activityNotes",
|
||||||
|
translation: activityNotesTranslation as unknown as AnyTranslation,
|
||||||
|
uniqueField: "id",
|
||||||
|
sourceIdField: "soActivityNotesRecId",
|
||||||
|
sourceUpdatedField: "lastUpdateUtc",
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -1875,7 +2026,16 @@ export const executeFullDalpuriSync = async (options?: {
|
|||||||
step.targetModel === "opportunity" ||
|
step.targetModel === "opportunity" ||
|
||||||
step.targetModel === "productData" ||
|
step.targetModel === "productData" ||
|
||||||
step.targetModel === "serviceTicketNote" ||
|
step.targetModel === "serviceTicketNote" ||
|
||||||
step.targetModel === "schedule"
|
step.targetModel === "schedule" ||
|
||||||
|
step.targetModel === "timeEntryStatus" ||
|
||||||
|
step.targetModel === "timeEntryChargeCode" ||
|
||||||
|
step.targetModel === "timeActivityClass" ||
|
||||||
|
step.targetModel === "timeActivityType" ||
|
||||||
|
step.targetModel === "timeEntry" ||
|
||||||
|
step.targetModel === "activityType" ||
|
||||||
|
step.targetModel === "activityStatus" ||
|
||||||
|
step.targetModel === "activity" ||
|
||||||
|
step.targetModel === "activityNotes"
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
await refreshContextFromApi(apiPrisma, context);
|
await refreshContextFromApi(apiPrisma, context);
|
||||||
@@ -1925,10 +2085,8 @@ export const executeFullDalpuriSync = async (options?: {
|
|||||||
? effectiveDecision.sourceIds
|
? effectiveDecision.sourceIds
|
||||||
: undefined;
|
: undefined;
|
||||||
console.log(
|
console.log(
|
||||||
` [smart-sync]${forceIncremental ? "[forced]" : ""} mode=${
|
` [smart-sync]${forceIncremental ? "[forced]" : ""} mode=${effectiveDecision.mode
|
||||||
effectiveDecision.mode
|
}${effectiveDecision.mode === "incremental"
|
||||||
}${
|
|
||||||
effectiveDecision.mode === "incremental"
|
|
||||||
? ` (${effectiveDecision.sourceIds.length} ids)`
|
? ` (${effectiveDecision.sourceIds.length} ids)`
|
||||||
: ""
|
: ""
|
||||||
}`
|
}`
|
||||||
@@ -1978,8 +2136,7 @@ export const executeFullDalpuriSync = async (options?: {
|
|||||||
if (forceIncremental) {
|
if (forceIncremental) {
|
||||||
const selected = deleteSteps[0];
|
const selected = deleteSteps[0];
|
||||||
console.log(
|
console.log(
|
||||||
`[delete-reconcile] incremental sweep: ${selected.name} (${
|
`[delete-reconcile] incremental sweep: ${selected.name} (${incrementalDeleteStepIndex + 1
|
||||||
incrementalDeleteStepIndex + 1
|
|
||||||
}/${steps.length})`
|
}/${steps.length})`
|
||||||
);
|
);
|
||||||
incrementalDeleteStepIndex =
|
incrementalDeleteStepIndex =
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
import { SoActivityNotes as CwSoActivityNotes } from "../../generated/prisma/client";
|
||||||
|
import { Translation, skipRow } from "./types";
|
||||||
|
import { TranslationContext } from "./context";
|
||||||
|
|
||||||
|
type ApiActivityNotesRecord = {
|
||||||
|
id: number;
|
||||||
|
notes: string;
|
||||||
|
activityId: number | null;
|
||||||
|
internalAnalysisFlag: boolean;
|
||||||
|
enteredById: string | null;
|
||||||
|
updatedById: string | null;
|
||||||
|
createdAt: Date;
|
||||||
|
updatedAt: Date;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const activityNotesTranslation: Translation<
|
||||||
|
CwSoActivityNotes,
|
||||||
|
ApiActivityNotesRecord,
|
||||||
|
TranslationContext
|
||||||
|
> = {
|
||||||
|
values: [
|
||||||
|
{ from: "soActivityNotesRecId", to: "id" },
|
||||||
|
{
|
||||||
|
from: "notes",
|
||||||
|
to: "notes",
|
||||||
|
process: (value: string) => value,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "soActivityRecId",
|
||||||
|
to: "activityId",
|
||||||
|
process: (value: number, context: TranslationContext) => {
|
||||||
|
if (!context.activityIds.has(value)) {
|
||||||
|
skipRow(`Activity ${value} not found in API`);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "internalAnalysisFlag",
|
||||||
|
to: "internalAnalysisFlag",
|
||||||
|
process: (value) => Boolean(value),
|
||||||
|
},
|
||||||
|
{ from: "enteredBy", to: "enteredById" },
|
||||||
|
{ from: "updatedBy", to: "updatedById" },
|
||||||
|
{ from: "dateCreatedUtc", to: "createdAt" },
|
||||||
|
{ from: "lastUpdateUtc", to: "updatedAt" },
|
||||||
|
],
|
||||||
|
};
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
import { SoActStatus as CwSoActStatus } from "../../generated/prisma/client";
|
||||||
|
import { Translation } from "./types";
|
||||||
|
|
||||||
|
type ApiActivityStatusRecord = {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
description: string | null;
|
||||||
|
closedFlag: boolean;
|
||||||
|
inactiveFlag: boolean;
|
||||||
|
defaultFlag: boolean;
|
||||||
|
spawnFollowupFlag: boolean;
|
||||||
|
createdById: string | null;
|
||||||
|
updatedById: string | null;
|
||||||
|
createdAt: Date;
|
||||||
|
updatedAt: Date;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const activityStatusTranslation: Translation<
|
||||||
|
CwSoActStatus,
|
||||||
|
ApiActivityStatusRecord
|
||||||
|
> = {
|
||||||
|
values: [
|
||||||
|
{ from: "soActStatusRecId", to: "id" },
|
||||||
|
{
|
||||||
|
from: "description",
|
||||||
|
to: "name",
|
||||||
|
process: (value) => (value ? value : "Unknown Status"),
|
||||||
|
},
|
||||||
|
{ from: "description", to: "description" },
|
||||||
|
{
|
||||||
|
from: "closedFlag",
|
||||||
|
to: "closedFlag",
|
||||||
|
process: (value) => Boolean(value),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "inactiveFlag",
|
||||||
|
to: "inactiveFlag",
|
||||||
|
process: (value) => Boolean(value),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "defaultFlag",
|
||||||
|
to: "defaultFlag",
|
||||||
|
process: (value) => Boolean(value),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "spawnFollowupFlag",
|
||||||
|
to: "spawnFollowupFlag",
|
||||||
|
process: (value) => Boolean(value),
|
||||||
|
},
|
||||||
|
{ from: "enteredBy", to: "createdById" },
|
||||||
|
{ from: "updatedBy", to: "updatedById" },
|
||||||
|
{ from: "dateEnteredUtc", to: "createdAt" },
|
||||||
|
{ from: "lastUpdateUtc", to: "updatedAt" },
|
||||||
|
],
|
||||||
|
};
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
import { SoActivityType as CwSoActivityType } from "../../generated/prisma/client";
|
||||||
|
import { Translation } from "./types";
|
||||||
|
|
||||||
|
type ApiActivityTypeRecord = {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
inactiveFlag: boolean;
|
||||||
|
historyFlag: boolean;
|
||||||
|
defaultFlag: boolean;
|
||||||
|
importFlag: boolean;
|
||||||
|
emailFlag: boolean;
|
||||||
|
memoFlag: boolean;
|
||||||
|
pointsValue: number | null;
|
||||||
|
createdById: string | null;
|
||||||
|
updatedById: string | null;
|
||||||
|
createdAt: Date;
|
||||||
|
updatedAt: Date;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const activityTypeTranslation: Translation<
|
||||||
|
CwSoActivityType,
|
||||||
|
ApiActivityTypeRecord
|
||||||
|
> = {
|
||||||
|
values: [
|
||||||
|
{ from: "soActivityTypeRecId", to: "id" },
|
||||||
|
{
|
||||||
|
from: "soActivityTypeId",
|
||||||
|
to: "name",
|
||||||
|
process: (value) => (value ? value : ""),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "description",
|
||||||
|
to: "description",
|
||||||
|
process: (value) => (value ? value : ""),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "inactiveFlag",
|
||||||
|
to: "inactiveFlag",
|
||||||
|
process: (value) => Boolean(value),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "historyFlag",
|
||||||
|
to: "historyFlag",
|
||||||
|
process: (value) => Boolean(value),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "defaultFlag",
|
||||||
|
to: "defaultFlag",
|
||||||
|
process: (value) => Boolean(value),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "importFlag",
|
||||||
|
to: "importFlag",
|
||||||
|
process: (value) => Boolean(value),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "emailFlag",
|
||||||
|
to: "emailFlag",
|
||||||
|
process: (value) => Boolean(value),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "memoFlag",
|
||||||
|
to: "memoFlag",
|
||||||
|
process: (value) => Boolean(value ?? false),
|
||||||
|
},
|
||||||
|
{ from: "pointsValue", to: "pointsValue" },
|
||||||
|
{ from: "enteredBy", to: "createdById" },
|
||||||
|
{ from: "updatedBy", to: "updatedById" },
|
||||||
|
{ from: "dateEnteredUtc", to: "createdAt" },
|
||||||
|
{ from: "lastUpdateUtc", to: "updatedAt" },
|
||||||
|
],
|
||||||
|
};
|
||||||
@@ -0,0 +1,147 @@
|
|||||||
|
import { SoActivity as CwSoActivity } from "../../generated/prisma/client";
|
||||||
|
import { Translation, skipRow } from "./types";
|
||||||
|
import { TranslationContext } from "./context";
|
||||||
|
|
||||||
|
type ApiActivityRecord = {
|
||||||
|
id: number;
|
||||||
|
subject: string;
|
||||||
|
startTime: Date;
|
||||||
|
endTime: Date;
|
||||||
|
assignToId: string;
|
||||||
|
assignedById: string;
|
||||||
|
enteredBy: string;
|
||||||
|
automated: boolean;
|
||||||
|
closedFlag: boolean;
|
||||||
|
notifyCompleteFlag: boolean;
|
||||||
|
notificationSentFlat: boolean;
|
||||||
|
opportunityId: string | null;
|
||||||
|
serviceTicketId: string | null;
|
||||||
|
contactId: number | null;
|
||||||
|
companyId: number | null;
|
||||||
|
activityTypeId: number | null;
|
||||||
|
activityStatusId: number | null;
|
||||||
|
createdById: string | null;
|
||||||
|
updatedById: string | null;
|
||||||
|
closedById: string | null;
|
||||||
|
closedAt: Date | null;
|
||||||
|
createdAt: Date;
|
||||||
|
updatedAt: Date;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const activityTranslation: Translation<
|
||||||
|
CwSoActivity,
|
||||||
|
ApiActivityRecord,
|
||||||
|
TranslationContext
|
||||||
|
> = {
|
||||||
|
values: [
|
||||||
|
{ from: "soActivityRecId", to: "id" },
|
||||||
|
{
|
||||||
|
from: "subject",
|
||||||
|
to: "subject",
|
||||||
|
process: (value) => (value ? value : ""),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "dateTimeStart",
|
||||||
|
to: "startTime",
|
||||||
|
process: (value) => {
|
||||||
|
if (!value) skipRow("Missing dateTimeStart");
|
||||||
|
return value as Date;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "dateTimeEnd",
|
||||||
|
to: "endTime",
|
||||||
|
process: (value) => {
|
||||||
|
if (!value) skipRow("Missing dateTimeEnd");
|
||||||
|
return value as Date;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "assignTo",
|
||||||
|
to: "assignToId",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "assignedBy",
|
||||||
|
to: "assignedById",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "enteredBy",
|
||||||
|
to: "enteredBy",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "automated",
|
||||||
|
to: "automated",
|
||||||
|
process: (value) => Boolean(value),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "closeFlag",
|
||||||
|
to: "closedFlag",
|
||||||
|
process: (value) => Boolean(value),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "notifyCompleteFlag",
|
||||||
|
to: "notifyCompleteFlag",
|
||||||
|
process: (value) => Boolean(value),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "notificationSentFlag",
|
||||||
|
to: "notificationSentFlat",
|
||||||
|
process: (value) => Boolean(value),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// opportunityId is a String? field with no @relation — store as null
|
||||||
|
// until a uid-mapping approach is established
|
||||||
|
from: "opportunityRecId",
|
||||||
|
to: "opportunityId",
|
||||||
|
process: () => null,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// serviceTicketId is a String? field with no @relation — store as null
|
||||||
|
// until a uid-mapping approach is established
|
||||||
|
from: "srServiceRecId",
|
||||||
|
to: "serviceTicketId",
|
||||||
|
process: () => null,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "contactRecId",
|
||||||
|
to: "contactId",
|
||||||
|
process: (value: number | null, context: TranslationContext) => {
|
||||||
|
if (!value) return null;
|
||||||
|
if (!context.contactIds.has(value)) return null;
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "companyRecId",
|
||||||
|
to: "companyId",
|
||||||
|
process: (value: number | null, context: TranslationContext) => {
|
||||||
|
if (!value) return null;
|
||||||
|
if (!context.companyIds.has(value)) return null;
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "soActivityTypeRecId",
|
||||||
|
to: "activityTypeId",
|
||||||
|
process: (value: number | null, context: TranslationContext) => {
|
||||||
|
if (!value) return null;
|
||||||
|
if (!context.activityTypeIds.has(value)) return null;
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "soActStatusRecId",
|
||||||
|
to: "activityStatusId",
|
||||||
|
process: (value: number, context: TranslationContext) => {
|
||||||
|
if (!context.activityStatusIds.has(value)) return null;
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ from: "enteredBy", to: "createdById" },
|
||||||
|
{ from: "updatedBy", to: "updatedById" },
|
||||||
|
{ from: "closedBy", to: "closedById" },
|
||||||
|
{ from: "dateClosedUtc", to: "closedAt" },
|
||||||
|
{ from: "dateEnteredUtc", to: "createdAt" },
|
||||||
|
{ from: "lastUpdatedUTC", to: "updatedAt" },
|
||||||
|
],
|
||||||
|
};
|
||||||
@@ -73,6 +73,21 @@ export interface TranslationContext {
|
|||||||
|
|
||||||
// Set of API TaxCode.id values for FK validation
|
// Set of API TaxCode.id values for FK validation
|
||||||
taxCodeIds: Set<number>;
|
taxCodeIds: Set<number>;
|
||||||
|
|
||||||
|
// Set of API ActivityType.id values for FK validation
|
||||||
|
activityTypeIds: Set<number>;
|
||||||
|
|
||||||
|
// Set of API ActivityStatus.id values for FK validation
|
||||||
|
activityStatusIds: Set<number>;
|
||||||
|
|
||||||
|
// Set of API Activity.id values for FK validation (used by ActivityNotes)
|
||||||
|
activityIds: Set<number>;
|
||||||
|
|
||||||
|
// Set of API TimeEntryChargeCode.id values for FK validation
|
||||||
|
timeEntryChargeCodeIds: Set<number>;
|
||||||
|
|
||||||
|
// Map: CW TE_Status_ID (smallint) -> API TimeEntryStatus.id (rec ID)
|
||||||
|
timeEntryStatusIdByTeStatusId: Map<number, number>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -103,5 +118,10 @@ export function createTranslationContext(): TranslationContext {
|
|||||||
scheduleTypeIds: new Set(),
|
scheduleTypeIds: new Set(),
|
||||||
scheduleSpanIds: new Set(),
|
scheduleSpanIds: new Set(),
|
||||||
taxCodeIds: new Set(),
|
taxCodeIds: new Set(),
|
||||||
|
activityTypeIds: new Set(),
|
||||||
|
activityStatusIds: new Set(),
|
||||||
|
activityIds: new Set(),
|
||||||
|
timeEntryChargeCodeIds: new Set(),
|
||||||
|
timeEntryStatusIdByTeStatusId: new Map(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
import { MemberType as CwMemberType } from "../../generated/prisma/client";
|
||||||
|
import { Translation } from "./types";
|
||||||
|
|
||||||
|
type ApiCwMemberTypeRecord = {
|
||||||
|
id: number;
|
||||||
|
description: string | null;
|
||||||
|
inactiveFlag: boolean;
|
||||||
|
createdById: string | null;
|
||||||
|
updatedById: string | null;
|
||||||
|
createdAt: Date;
|
||||||
|
updatedAt: Date;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const cwMemberTypeTranslation: Translation<
|
||||||
|
CwMemberType,
|
||||||
|
ApiCwMemberTypeRecord
|
||||||
|
> = {
|
||||||
|
values: [
|
||||||
|
{ from: "memberTypeRecId", to: "id" },
|
||||||
|
{ from: "description", to: "description" },
|
||||||
|
{
|
||||||
|
from: "inactiveFlag",
|
||||||
|
to: "inactiveFlag",
|
||||||
|
process: (value) => Boolean(value),
|
||||||
|
},
|
||||||
|
{ from: "enteredBy", to: "createdById" },
|
||||||
|
{ from: "updatedBy", to: "updatedById" },
|
||||||
|
{
|
||||||
|
from: "dateEnteredUtc",
|
||||||
|
to: "createdAt",
|
||||||
|
process: (value) => (value as Date | null) ?? new Date(0),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "lastUpdateUtc",
|
||||||
|
to: "updatedAt",
|
||||||
|
process: (value) => (value as Date | null) ?? new Date(0),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
import { ActivityClass as CwActivityClass } from "../../generated/prisma/client";
|
||||||
|
import { Translation } from "./types";
|
||||||
|
|
||||||
|
type ApiTimeActivityClassRecord = {
|
||||||
|
id: number;
|
||||||
|
description: string | null;
|
||||||
|
hourlyRate: number | null;
|
||||||
|
inactiveFlag: boolean;
|
||||||
|
taxExemptFlag: boolean;
|
||||||
|
createdById: string | null;
|
||||||
|
updatedById: string | null;
|
||||||
|
createdAt: Date;
|
||||||
|
updatedAt: Date;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const timeActivityClassTranslation: Translation<
|
||||||
|
CwActivityClass,
|
||||||
|
ApiTimeActivityClassRecord
|
||||||
|
> = {
|
||||||
|
values: [
|
||||||
|
{ from: "activityClassRecId", to: "id" },
|
||||||
|
{ from: "description", to: "description" },
|
||||||
|
{
|
||||||
|
from: "hourlyRate",
|
||||||
|
to: "hourlyRate",
|
||||||
|
process: (value) => (value != null ? Number(value) : null),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "inactiveFlag",
|
||||||
|
to: "inactiveFlag",
|
||||||
|
process: (value) => Boolean(value),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "taxExemptFlag",
|
||||||
|
to: "taxExemptFlag",
|
||||||
|
process: (value) => Boolean(value),
|
||||||
|
},
|
||||||
|
{ from: "enteredBy", to: "createdById" },
|
||||||
|
{ from: "updatedBy", to: "updatedById" },
|
||||||
|
{
|
||||||
|
from: "dateEnteredUtc",
|
||||||
|
to: "createdAt",
|
||||||
|
process: (value) => (value as Date | null) ?? new Date(0),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "lastUpdatedUtc",
|
||||||
|
to: "updatedAt",
|
||||||
|
process: (value) => (value as Date | null) ?? new Date(0),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
import { ActivityType as CwActivityType } from "../../generated/prisma/client";
|
||||||
|
import { Translation } from "./types";
|
||||||
|
|
||||||
|
type ApiTimeActivityTypeRecord = {
|
||||||
|
id: number;
|
||||||
|
description: string | null;
|
||||||
|
minHours: number | null;
|
||||||
|
maxHours: number | null;
|
||||||
|
rate: number | null;
|
||||||
|
costMultiplier: number;
|
||||||
|
inactiveFlag: boolean;
|
||||||
|
invoiceFlag: boolean;
|
||||||
|
billableFlag: boolean;
|
||||||
|
utilizationFlag: boolean;
|
||||||
|
defaultFlag: boolean;
|
||||||
|
multiplierFlag: boolean;
|
||||||
|
createdById: string | null;
|
||||||
|
updatedById: string | null;
|
||||||
|
createdAt: Date;
|
||||||
|
updatedAt: Date;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const timeActivityTypeTranslation: Translation<
|
||||||
|
CwActivityType,
|
||||||
|
ApiTimeActivityTypeRecord
|
||||||
|
> = {
|
||||||
|
values: [
|
||||||
|
{ from: "activityTypeRecId", to: "id" },
|
||||||
|
{ from: "description", to: "description" },
|
||||||
|
{
|
||||||
|
from: "hoursMin",
|
||||||
|
to: "minHours",
|
||||||
|
process: (value) => (value != null ? Number(value) : null),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "hoursMax",
|
||||||
|
to: "maxHours",
|
||||||
|
process: (value) => (value != null ? Number(value) : null),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "rate",
|
||||||
|
to: "rate",
|
||||||
|
process: (value) => (value != null ? Number(value) : null),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "costMultiplier",
|
||||||
|
to: "costMultiplier",
|
||||||
|
process: (value) => (value != null ? Number(value) : 1),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "inactiveFlag",
|
||||||
|
to: "inactiveFlag",
|
||||||
|
process: (value) => Boolean(value),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "invoiceFlag",
|
||||||
|
to: "invoiceFlag",
|
||||||
|
process: (value) => Boolean(value),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "billableFlag",
|
||||||
|
to: "billableFlag",
|
||||||
|
process: (value) => Boolean(value),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "utilizationFlag",
|
||||||
|
to: "utilizationFlag",
|
||||||
|
process: (value) => Boolean(value),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "defaultFlag",
|
||||||
|
to: "defaultFlag",
|
||||||
|
process: (value) => Boolean(value ?? false),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "multiplierFlag",
|
||||||
|
to: "multiplierFlag",
|
||||||
|
process: (value) => Boolean(value),
|
||||||
|
},
|
||||||
|
{ from: "enteredBy", to: "createdById" },
|
||||||
|
{ from: "updatedBy", to: "updatedById" },
|
||||||
|
{
|
||||||
|
from: "dateEnteredUtc",
|
||||||
|
to: "createdAt",
|
||||||
|
process: (value) => (value as Date | null) ?? new Date(0),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "lastUpdatedUtc",
|
||||||
|
to: "updatedAt",
|
||||||
|
process: (value) => (value as Date | null) ?? new Date(0),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
import { TeChargeCode as CwTeChargeCode } from "../../generated/prisma/client";
|
||||||
|
import { Translation } from "./types";
|
||||||
|
|
||||||
|
type ApiTimeEntryChargeCodeRecord = {
|
||||||
|
id: number;
|
||||||
|
chargeCodeId: number;
|
||||||
|
description: string | null;
|
||||||
|
expenseFlag: boolean;
|
||||||
|
timeFlag: boolean;
|
||||||
|
billableFlag: boolean;
|
||||||
|
invoiceFlag: boolean;
|
||||||
|
createdById: string | null;
|
||||||
|
updatedById: string | null;
|
||||||
|
createdAt: Date;
|
||||||
|
updatedAt: Date;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const timeEntryChargeCodeTranslation: Translation<
|
||||||
|
CwTeChargeCode,
|
||||||
|
ApiTimeEntryChargeCodeRecord
|
||||||
|
> = {
|
||||||
|
values: [
|
||||||
|
{ from: "teChargeCodeRecId", to: "id" },
|
||||||
|
{ from: "teChargeCodeRecId", to: "chargeCodeId" },
|
||||||
|
{ from: "description", to: "description" },
|
||||||
|
{
|
||||||
|
from: "expenseFlag",
|
||||||
|
to: "expenseFlag",
|
||||||
|
process: (value) => Boolean(value),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "timeFlag",
|
||||||
|
to: "timeFlag",
|
||||||
|
process: (value) => Boolean(value),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "billableFlag",
|
||||||
|
to: "billableFlag",
|
||||||
|
process: (value) => Boolean(value),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "invoiceFlag",
|
||||||
|
to: "invoiceFlag",
|
||||||
|
process: (value) => Boolean(value ?? false),
|
||||||
|
},
|
||||||
|
{ from: "enteredBy", to: "createdById" },
|
||||||
|
{ from: "updatedBy", to: "updatedById" },
|
||||||
|
{
|
||||||
|
from: "dateEnteredUtc",
|
||||||
|
to: "createdAt",
|
||||||
|
process: (value) => (value as Date | null) ?? new Date(0),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "lastUpdateUtc",
|
||||||
|
to: "updatedAt",
|
||||||
|
process: (value) => (value as Date | null) ?? new Date(0),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import { TeStatus as CwTeStatus } from "../../generated/prisma/client";
|
||||||
|
import { Translation } from "./types";
|
||||||
|
|
||||||
|
type ApiTimeEntryStatusRecord = {
|
||||||
|
id: number;
|
||||||
|
statusId: number;
|
||||||
|
description: string | null;
|
||||||
|
action: string | null;
|
||||||
|
createdAt: Date;
|
||||||
|
updatedAt: Date;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const timeEntryStatusTranslation: Translation<
|
||||||
|
CwTeStatus,
|
||||||
|
ApiTimeEntryStatusRecord
|
||||||
|
> = {
|
||||||
|
values: [
|
||||||
|
{ from: "teStatusRecId", to: "id" },
|
||||||
|
{ from: "teStatusId", to: "statusId" },
|
||||||
|
{ from: "description", to: "description" },
|
||||||
|
{ from: "action", to: "action" },
|
||||||
|
{
|
||||||
|
from: "lastUpdatedUtc",
|
||||||
|
to: "createdAt",
|
||||||
|
process: (value) => (value as Date | null) ?? new Date(0),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "lastUpdatedUtc",
|
||||||
|
to: "updatedAt",
|
||||||
|
process: (value) => (value as Date | null) ?? new Date(0),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
@@ -0,0 +1,208 @@
|
|||||||
|
import { TimeEntry as CwTimeEntry } from "../../generated/prisma/client";
|
||||||
|
import { Translation, skipRow } from "./types";
|
||||||
|
import { TranslationContext } from "./context";
|
||||||
|
|
||||||
|
type ApiTimeEntryRecord = {
|
||||||
|
id: number;
|
||||||
|
uid: string;
|
||||||
|
memberId: string | null;
|
||||||
|
companyId: number;
|
||||||
|
serviceTicketId: number | null;
|
||||||
|
activityId: number | null;
|
||||||
|
chargeCodeId: number | null;
|
||||||
|
statusId: number | null;
|
||||||
|
contactId: number | null;
|
||||||
|
dateStart: Date | null;
|
||||||
|
timeStart: Date | null;
|
||||||
|
timeEnd: Date | null;
|
||||||
|
notes: string | null;
|
||||||
|
notesMd: string | null;
|
||||||
|
internalNote: string | null;
|
||||||
|
billableHours: number | null;
|
||||||
|
actualHours: number | null;
|
||||||
|
invoicedHours: number | null;
|
||||||
|
deductedHours: number | null;
|
||||||
|
hourlyRate: number | null;
|
||||||
|
effectiveRate: number | null;
|
||||||
|
issueFlag: boolean;
|
||||||
|
mergedFlag: boolean;
|
||||||
|
invoiceFlag: boolean;
|
||||||
|
billableFlag: boolean;
|
||||||
|
documentFlag: boolean;
|
||||||
|
teProblemFlag: boolean;
|
||||||
|
teResolutionFlag: boolean;
|
||||||
|
teInternalAnalysisFlag: boolean;
|
||||||
|
chargeToRecId: number | null;
|
||||||
|
chargeToType: string | null;
|
||||||
|
createdById: string | null;
|
||||||
|
updatedById: string | null;
|
||||||
|
originalAuthorId: string | null;
|
||||||
|
createdAt: Date;
|
||||||
|
updatedAt: Date;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const timeEntryTranslation: Translation<
|
||||||
|
CwTimeEntry,
|
||||||
|
ApiTimeEntryRecord,
|
||||||
|
TranslationContext
|
||||||
|
> = {
|
||||||
|
values: [
|
||||||
|
{ from: "timeRecId", to: "id" },
|
||||||
|
{
|
||||||
|
from: "mobileGuid",
|
||||||
|
to: "uid",
|
||||||
|
process: (value: string) => value,
|
||||||
|
},
|
||||||
|
{ from: "memberId", to: "memberId" },
|
||||||
|
{
|
||||||
|
from: "companyRecId",
|
||||||
|
to: "companyId",
|
||||||
|
process: (value: number, context: TranslationContext) => {
|
||||||
|
if (!context.companyIds.has(value)) return skipRow(`company ${value} not found`);
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "srServiceRecId",
|
||||||
|
to: "serviceTicketId",
|
||||||
|
process: (value: number | null, context: TranslationContext) => {
|
||||||
|
if (!value) return null;
|
||||||
|
if (!context.serviceTicketIds.has(value)) return null;
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "soActivityRecId",
|
||||||
|
to: "activityId",
|
||||||
|
process: (value: number | null, context: TranslationContext) => {
|
||||||
|
if (!value) return null;
|
||||||
|
if (!context.activityIds.has(value)) return null;
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "teChargeCodeRecId",
|
||||||
|
to: "chargeCodeId",
|
||||||
|
process: (value: number | null, context: TranslationContext) => {
|
||||||
|
if (!value) return null;
|
||||||
|
if (!context.timeEntryChargeCodeIds.has(value)) return null;
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "teStatusId",
|
||||||
|
to: "statusId",
|
||||||
|
process: (value: number, context: TranslationContext) => {
|
||||||
|
return context.timeEntryStatusIdByTeStatusId.get(value) ?? null;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "contactRecId",
|
||||||
|
to: "contactId",
|
||||||
|
process: (value: number | null, context: TranslationContext) => {
|
||||||
|
if (!value) return null;
|
||||||
|
if (!context.contactIds.has(value)) return null;
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ from: "dateStart", to: "dateStart" },
|
||||||
|
{ from: "timeStart", to: "timeStart" },
|
||||||
|
{ from: "timeEnd", to: "timeEnd" },
|
||||||
|
{
|
||||||
|
from: "notes",
|
||||||
|
to: "notes",
|
||||||
|
process: (value: string | null) => value ?? null,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "notesMarkdown",
|
||||||
|
to: "notesMd",
|
||||||
|
process: (value: string | null) => value ?? null,
|
||||||
|
},
|
||||||
|
{ from: "internalNote", to: "internalNote" },
|
||||||
|
{
|
||||||
|
from: "hoursBill",
|
||||||
|
to: "billableHours",
|
||||||
|
process: (value) => (value != null ? Number(value) : null),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "hoursActual",
|
||||||
|
to: "actualHours",
|
||||||
|
process: (value) => (value != null ? Number(value) : null),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "hoursInvoiced",
|
||||||
|
to: "invoicedHours",
|
||||||
|
process: (value) => (value != null ? Number(value) : null),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "hoursDeduct",
|
||||||
|
to: "deductedHours",
|
||||||
|
process: (value) => (value != null ? Number(value) : null),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "hourlyRate",
|
||||||
|
to: "hourlyRate",
|
||||||
|
process: (value) => (value != null ? Number(value) : null),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "effectiveRate",
|
||||||
|
to: "effectiveRate",
|
||||||
|
process: (value) => (value != null ? Number(value) : null),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "issueFlag",
|
||||||
|
to: "issueFlag",
|
||||||
|
process: (value) => Boolean(value),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "mergedFlag",
|
||||||
|
to: "mergedFlag",
|
||||||
|
process: (value) => Boolean(value),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "invoiceFlag",
|
||||||
|
to: "invoiceFlag",
|
||||||
|
process: (value) => Boolean(value),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "billableFlag",
|
||||||
|
to: "billableFlag",
|
||||||
|
process: (value) => Boolean(value),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "documentFlag",
|
||||||
|
to: "documentFlag",
|
||||||
|
process: (value) => Boolean(value),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "teProblemFlag",
|
||||||
|
to: "teProblemFlag",
|
||||||
|
process: (value) => Boolean(value),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "teResolutionFlag",
|
||||||
|
to: "teResolutionFlag",
|
||||||
|
process: (value) => Boolean(value),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "teInternalAnalysisFlag",
|
||||||
|
to: "teInternalAnalysisFlag",
|
||||||
|
process: (value) => Boolean(value),
|
||||||
|
},
|
||||||
|
{ from: "chargeToRecId", to: "chargeToRecId" },
|
||||||
|
{ from: "chargeToType", to: "chargeToType" },
|
||||||
|
{ from: "enteredBy", to: "createdById" },
|
||||||
|
{ from: "updatedBy", to: "updatedById" },
|
||||||
|
{ from: "originalAuthor", to: "originalAuthorId" },
|
||||||
|
{
|
||||||
|
from: "dateEnteredUtc",
|
||||||
|
to: "createdAt",
|
||||||
|
process: (value) => (value as Date | null) ?? new Date(0),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "lastUpdateUtc",
|
||||||
|
to: "updatedAt",
|
||||||
|
process: (value) => (value as Date | null) ?? new Date(0),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
@@ -206,12 +206,27 @@ export interface OpportunityActivity {
|
|||||||
closedAt?: string;
|
closedAt?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface WorkflowTimeEntry {
|
||||||
|
id: string;
|
||||||
|
cwId: number;
|
||||||
|
memberId?: string | null;
|
||||||
|
dateStart?: string | null;
|
||||||
|
timeStart?: string | null;
|
||||||
|
timeEnd?: string | null;
|
||||||
|
notes?: string | null;
|
||||||
|
actualHours?: number | null;
|
||||||
|
billableHours?: number | null;
|
||||||
|
billableFlag?: boolean | null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface WorkflowHistoryEntry {
|
export interface WorkflowHistoryEntry {
|
||||||
activity: OpportunityActivity;
|
activity: OpportunityActivity;
|
||||||
optimaType: string;
|
optimaType: string;
|
||||||
quoteId?: string | null;
|
quoteId?: string | null;
|
||||||
|
parentActivityId?: number | null;
|
||||||
closed?: boolean;
|
closed?: boolean;
|
||||||
closedAt?: string | null;
|
closedAt?: string | null;
|
||||||
|
timeEntries?: WorkflowTimeEntry[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface WorkflowHistoryResponse {
|
export interface WorkflowHistoryResponse {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
import { clientFetch } from "$lib/client-fetch";
|
import { clientFetch } from "$lib/client-fetch";
|
||||||
import type {
|
import type {
|
||||||
WorkflowHistoryEntry,
|
WorkflowHistoryEntry,
|
||||||
|
WorkflowTimeEntry,
|
||||||
OpportunityActivity,
|
OpportunityActivity,
|
||||||
} from "$lib/optima-api/modules/sales";
|
} from "$lib/optima-api/modules/sales";
|
||||||
import { formatDateTime } from "../types";
|
import { formatDateTime } from "../types";
|
||||||
@@ -152,53 +153,71 @@
|
|||||||
return { late: false, days: 0 };
|
return { late: false, days: 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── Tree node types ───────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
type ActivityNode = {
|
||||||
|
kind: "activity";
|
||||||
|
item: WorkflowHistoryEntry;
|
||||||
|
depth: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
type TimeEntryNode = {
|
||||||
|
kind: "timeEntry";
|
||||||
|
entry: WorkflowTimeEntry;
|
||||||
|
depth: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
type TreeNode = ActivityNode | TimeEntryNode;
|
||||||
|
|
||||||
/** Combine CW activities with workflow history into a unified timeline, sorted by creation date */
|
/** Combine CW activities with workflow history into a unified timeline, sorted by creation date */
|
||||||
$: timelineItems = (() => {
|
$: timelineItems = (() => {
|
||||||
let items;
|
let items: WorkflowHistoryEntry[];
|
||||||
// If we have workflow history, use that (it's already filtered + enriched)
|
|
||||||
if (workflowHistory.length > 0) {
|
if (workflowHistory.length > 0) {
|
||||||
items = workflowHistory.map((h) => ({
|
items = workflowHistory;
|
||||||
activity: h.activity,
|
|
||||||
optimaType: h.optimaType,
|
|
||||||
quoteId: h.quoteId ?? null,
|
|
||||||
closed: h.closed ?? null,
|
|
||||||
closedAt: h.closedAt ?? null,
|
|
||||||
isWorkflow: true,
|
|
||||||
}));
|
|
||||||
} else {
|
} else {
|
||||||
// Fall back to raw activities
|
|
||||||
items = (activities ?? []).map((a) => ({
|
items = (activities ?? []).map((a) => ({
|
||||||
activity: a,
|
activity: a,
|
||||||
optimaType: getOptimaType(a),
|
optimaType: getOptimaType(a) ?? "",
|
||||||
quoteId: null as string | null,
|
quoteId: null,
|
||||||
closed: null as boolean | null,
|
parentActivityId: null,
|
||||||
closedAt: null as string | null,
|
closed: null as unknown as boolean,
|
||||||
isWorkflow: false,
|
closedAt: null,
|
||||||
|
timeEntries: [],
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
// Sort by creation date (cwDateEntered or dateStart), newest first
|
// Sort by creation date (cwDateEntered or dateStart), newest first
|
||||||
return items.sort((a, b) => {
|
return items.slice().sort((a, b) => {
|
||||||
const dateA = a.activity.cwDateEntered ?? a.activity.dateStart ?? "";
|
const dateA = a.activity.cwDateEntered ?? a.activity.dateStart ?? "";
|
||||||
const dateB = b.activity.cwDateEntered ?? b.activity.dateStart ?? "";
|
const dateB = b.activity.cwDateEntered ?? b.activity.dateStart ?? "";
|
||||||
return dateB.localeCompare(dateA);
|
return dateB.localeCompare(dateA);
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|
||||||
/** Build a flat tree: root items first, then their children immediately after (for parent hierarchy display) */
|
/**
|
||||||
|
* Build a flat tree interleaving time entries at the correct depth.
|
||||||
|
*
|
||||||
|
* Inverted tree: children and time entries appear ABOVE the activity they
|
||||||
|
* belong to, so work done under a workflow step is visible before the step
|
||||||
|
* itself in the timeline.
|
||||||
|
*
|
||||||
|
* Algorithm:
|
||||||
|
* 1. Resolve parent-child relationships between activities using parentActivityId.
|
||||||
|
* 2. For each activity, first recursively insert its child activities, then its
|
||||||
|
* time entries (sorted dateStart asc), then the activity node itself.
|
||||||
|
*/
|
||||||
$: flatTree = (() => {
|
$: flatTree = (() => {
|
||||||
const idToItem = new Map(
|
// Map cwActivityId → WorkflowHistoryEntry
|
||||||
|
const idToItem = new Map<number, WorkflowHistoryEntry>(
|
||||||
timelineItems.map((item) => [item.activity.cwActivityId, item]),
|
timelineItems.map((item) => [item.activity.cwActivityId, item]),
|
||||||
);
|
);
|
||||||
const childrenMap = new Map<number, (typeof timelineItems)[0][]>();
|
|
||||||
const roots: (typeof timelineItems)[0][] = [];
|
// Build children map: parentCwId → child items
|
||||||
|
const childrenMap = new Map<number, WorkflowHistoryEntry[]>();
|
||||||
|
const roots: WorkflowHistoryEntry[] = [];
|
||||||
|
|
||||||
for (const item of timelineItems) {
|
for (const item of timelineItems) {
|
||||||
const parentId = getParentActivityId(item.activity);
|
const parentId = item.parentActivityId ?? null;
|
||||||
if (
|
if (parentId != null && idToItem.has(parentId)) {
|
||||||
parentId != null &&
|
|
||||||
item.activity.cwActivityId != null &&
|
|
||||||
idToItem.has(parentId)
|
|
||||||
) {
|
|
||||||
if (!childrenMap.has(parentId)) childrenMap.set(parentId, []);
|
if (!childrenMap.has(parentId)) childrenMap.set(parentId, []);
|
||||||
childrenMap.get(parentId)!.push(item);
|
childrenMap.get(parentId)!.push(item);
|
||||||
} else {
|
} else {
|
||||||
@@ -206,16 +225,34 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const flat: Array<(typeof timelineItems)[0] & { depth: number }> = [];
|
const flat: TreeNode[] = [];
|
||||||
|
|
||||||
|
function insertActivity(item: WorkflowHistoryEntry, depth: number) {
|
||||||
|
const cwId = item.activity.cwActivityId;
|
||||||
|
|
||||||
|
// 1. Child activities first (inverted: children above parent)
|
||||||
|
for (const child of childrenMap.get(cwId) ?? []) {
|
||||||
|
insertActivity(child, depth + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Time entries for this activity, sorted by dateStart asc
|
||||||
|
const entries = (item.timeEntries ?? []).slice().sort((a, b) => {
|
||||||
|
const da = a.dateStart ?? a.timeStart ?? "";
|
||||||
|
const db = b.dateStart ?? b.timeStart ?? "";
|
||||||
|
return da.localeCompare(db);
|
||||||
|
});
|
||||||
|
for (const entry of entries) {
|
||||||
|
flat.push({ kind: "timeEntry", entry, depth: depth + 1 });
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. The activity node itself (below its children)
|
||||||
|
flat.push({ kind: "activity", item, depth });
|
||||||
|
}
|
||||||
|
|
||||||
for (const root of roots) {
|
for (const root of roots) {
|
||||||
flat.push({ ...root, depth: 0 });
|
insertActivity(root, 0);
|
||||||
const rootId = root.activity.cwActivityId;
|
|
||||||
if (rootId != null) {
|
|
||||||
for (const child of childrenMap.get(rootId) ?? []) {
|
|
||||||
flat.push({ ...child, depth: 1 });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return flat;
|
return flat;
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
@@ -299,13 +336,84 @@
|
|||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
<div class="at-timeline">
|
<div class="at-timeline">
|
||||||
{#each flatTree as item, i ((item.activity.cwActivityId ?? i) + "-d" + item.depth)}
|
{#each flatTree as node, i (node.kind === "activity" ? `act-${node.item.activity.cwActivityId}-d${node.depth}` : `te-${node.entry.id}-d${node.depth}`)}
|
||||||
|
{#if node.kind === "timeEntry"}
|
||||||
|
{@const te = node.entry}
|
||||||
|
{@const hasAbove = i > 0}
|
||||||
|
{@const hasD1Above = i > 0 && flatTree[i - 1].depth >= 2}
|
||||||
|
<div
|
||||||
|
class="at-entry at-entry-time-entry"
|
||||||
|
style="--at-depth: {node.depth}"
|
||||||
|
>
|
||||||
|
<div class="at-connector" data-depth="{node.depth}" class:at-has-above={hasAbove} class:at-has-d1-above={hasD1Above}>
|
||||||
|
<div class="at-branch"></div>
|
||||||
|
<div class="at-dot at-dot-time-entry">
|
||||||
|
<!-- Clock icon -->
|
||||||
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="12" height="12">
|
||||||
|
<circle cx="12" cy="12" r="10" /><polyline points="12 6 12 12 16 14" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="at-content">
|
||||||
|
<div class="at-content-header">
|
||||||
|
<span class="at-type-badge at-type-time-entry">Time Entry</span>
|
||||||
|
{#if te.billableFlag}
|
||||||
|
<span class="at-open-badge">Billable</span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{#if te.notes}
|
||||||
|
<p class="at-notes">{te.notes}</p>
|
||||||
|
{/if}
|
||||||
|
<div class="at-meta">
|
||||||
|
{#if te.memberId}
|
||||||
|
<span class="at-user">
|
||||||
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="12" height="12">
|
||||||
|
<path d="M20 21v-2a4 4 0 00-4-4H8a4 4 0 00-4 4v2" /><circle cx="12" cy="7" r="4" />
|
||||||
|
</svg>
|
||||||
|
{te.memberId}
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
{#if te.actualHours != null}
|
||||||
|
<span class="at-timestamp">
|
||||||
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="11" height="11">
|
||||||
|
<circle cx="12" cy="12" r="10" /><polyline points="12 6 12 12 16 14" />
|
||||||
|
</svg>
|
||||||
|
{te.actualHours}h
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
{#if te.timeStart}
|
||||||
|
<span class="at-timestamp at-schedule-time">
|
||||||
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="11" height="11">
|
||||||
|
<rect x="3" y="4" width="18" height="18" rx="2" ry="2" />
|
||||||
|
<line x1="16" y1="2" x2="16" y2="6" />
|
||||||
|
<line x1="8" y1="2" x2="8" y2="6" />
|
||||||
|
<line x1="3" y1="10" x2="21" y2="10" />
|
||||||
|
</svg>
|
||||||
|
{formatDateTime(te.timeStart)}{#if te.timeEnd} – {formatDateTime(te.timeEnd)}{/if}
|
||||||
|
</span>
|
||||||
|
{:else if te.dateStart}
|
||||||
|
<span class="at-timestamp">{formatDateTime(te.dateStart)}</span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
|
{@const item = node.item}
|
||||||
{@const act = item.activity}
|
{@const act = item.activity}
|
||||||
{@const transition = parseStatusTransition(act.notes)}
|
{@const transition = parseStatusTransition(act.notes)}
|
||||||
{@const open = item.closed != null ? !item.closed : isOpenActivity(act)}
|
{@const open = item.closed != null ? !item.closed : isOpenActivity(act)}
|
||||||
<div class="at-entry" class:at-entry-open={open} class:at-entry-child={item.depth > 0}>
|
{@const hasAbove = i > 0}
|
||||||
|
{@const hasD1Above = i > 0 && flatTree[i - 1].depth >= 2}
|
||||||
|
<div
|
||||||
|
class="at-entry"
|
||||||
|
class:at-entry-open={open}
|
||||||
|
style="--at-depth: {node.depth}"
|
||||||
|
>
|
||||||
<!-- Timeline connector -->
|
<!-- Timeline connector -->
|
||||||
<div class="at-connector">
|
<div class="at-connector" data-depth="{node.depth}" class:at-has-above={hasAbove} class:at-has-d1-above={hasD1Above}>
|
||||||
|
{#if node.depth > 0}
|
||||||
|
<div class="at-branch"></div>
|
||||||
|
{/if}
|
||||||
<div
|
<div
|
||||||
class="at-dot"
|
class="at-dot"
|
||||||
class:at-dot-open={open}
|
class:at-dot-open={open}
|
||||||
@@ -322,7 +430,7 @@
|
|||||||
<path d={optimaTypeIcon(item.optimaType)} />
|
<path d={optimaTypeIcon(item.optimaType)} />
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
{#if i < timelineItems.length - 1}
|
{#if node.depth === 0 && i < flatTree.length - 1}
|
||||||
<div class="at-line"></div>
|
<div class="at-line"></div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
@@ -492,6 +600,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{/if}
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -6097,32 +6097,92 @@
|
|||||||
/* Subtle highlight for open/active activities */
|
/* Subtle highlight for open/active activities */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Nested child activities (parent-child hierarchy via Parent_Activity field) */
|
/* Time entry rows */
|
||||||
.at-entry.at-entry-child {
|
.at-entry.at-entry-time-entry {
|
||||||
margin-left: 28px;
|
opacity: 0.88;
|
||||||
position: relative;
|
|
||||||
}
|
}
|
||||||
.at-entry.at-entry-child::before {
|
|
||||||
|
.at-dot.at-dot-time-entry {
|
||||||
|
background: rgba(168, 85, 247, 0.12);
|
||||||
|
color: #a855f7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.at-type-badge.at-type-time-entry {
|
||||||
|
background: rgba(168, 85, 247, 0.12);
|
||||||
|
color: #a855f7;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Connector (dots, lines, branches) ── */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The connector column grows wider with depth so that all ancestor rails,
|
||||||
|
* the branch arm, and the dot all fit without any margin-left on the entry.
|
||||||
|
*
|
||||||
|
* depth 0 → 20px (just the dot)
|
||||||
|
* depth 1 → 48px (28px rail space + dot)
|
||||||
|
* depth 2 → 76px (56px rail space + dot)
|
||||||
|
*
|
||||||
|
* Dot is always at the RIGHT edge of the connector.
|
||||||
|
* Dot center from left-edge = depth * 28 + 10.
|
||||||
|
*/
|
||||||
|
.at-connector {
|
||||||
|
position: relative;
|
||||||
|
width: calc(20px + var(--at-depth, 0) * 28px);
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pass-through rails — ancestor vertical lines that continue the full
|
||||||
|
* height of this entry so root-level rails are never interrupted by
|
||||||
|
* nested items sitting between two root entries.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* depth ≥ 1: depth-0 rail at X=9 */
|
||||||
|
.at-connector[data-depth="1"]::before,
|
||||||
|
.at-connector[data-depth="2"]::before {
|
||||||
content: "";
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: -16px;
|
left: 9px;
|
||||||
top: 12px;
|
top: 10px; /* default: start at dot centre — no stub above curve */
|
||||||
width: 12px;
|
bottom: 0;
|
||||||
height: 2px;
|
width: 2px;
|
||||||
background: var(--card-border);
|
background: var(--card-border);
|
||||||
|
z-index: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── Connector (dots + lines) ── */
|
/* When there IS any item above, extend the depth-0 rail to the top */
|
||||||
.at-connector {
|
.at-connector[data-depth="1"].at-has-above::before,
|
||||||
display: flex;
|
.at-connector[data-depth="2"].at-has-above::before {
|
||||||
flex-direction: column;
|
top: 0;
|
||||||
align-items: center;
|
|
||||||
width: 20px;
|
|
||||||
flex-shrink: 0;
|
|
||||||
padding-top: 2px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* depth ≥ 2: depth-1 rail at X=37 */
|
||||||
|
.at-connector[data-depth="2"]::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
left: 37px;
|
||||||
|
top: 10px; /* default: no stub above curve */
|
||||||
|
bottom: 0;
|
||||||
|
width: 2px;
|
||||||
|
background: var(--card-border);
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Only extend depth-1 rail to top when another depth-2 item is directly above
|
||||||
|
(depth-0 and depth-1 items have no line at x=37, so top:0 would create a stub) */
|
||||||
|
.at-connector[data-depth="2"].at-has-d1-above::after {
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Dot: positioned at the top-right corner of the connector column.
|
||||||
|
* „top: 0" means the previous entry's exit line ends exactly at this
|
||||||
|
* dot's top edge — creating a seamless "line enters the circle" effect.
|
||||||
|
*/
|
||||||
.at-dot {
|
.at-dot {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
width: 20px;
|
width: 20px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
@@ -6131,7 +6191,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
flex-shrink: 0;
|
z-index: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.at-dot.at-dot-open {
|
.at-dot.at-dot-open {
|
||||||
@@ -6144,11 +6204,54 @@
|
|||||||
color: #6b7280;
|
color: #6b7280;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Vertical exit line: runs from the dot's bottom edge to the connector
|
||||||
|
* bottom. The next entry's dot starts at Y=0, so this line ends exactly
|
||||||
|
* where the next dot begins — creating a seamless connection.
|
||||||
|
*
|
||||||
|
* left = depth * 28 + 9 (1px left of the dot's horizontal center)
|
||||||
|
*/
|
||||||
.at-line {
|
.at-line {
|
||||||
|
position: absolute;
|
||||||
|
left: calc(var(--at-depth, 0) * 28px + 9px);
|
||||||
|
top: 20px;
|
||||||
|
bottom: 0;
|
||||||
width: 2px;
|
width: 2px;
|
||||||
flex: 1;
|
|
||||||
background: var(--card-border);
|
background: var(--card-border);
|
||||||
min-height: 16px;
|
z-index: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* L-shaped branch: only rendered for depth > 0.
|
||||||
|
* Inverted tree: parent is BELOW, so the arm rises from dot-center downward
|
||||||
|
* toward the parent rail. Corner is at TOP-LEFT: the horizontal segment runs
|
||||||
|
* right from the rail into the dot's left edge at its centre (Y = 10), and the
|
||||||
|
* vertical segment descends from Y=10 toward the parent below.
|
||||||
|
*
|
||||||
|
* top: 10px → starts at dot vertical centre
|
||||||
|
* height: 10px → just the corner piece descending from centre
|
||||||
|
* border-top + border-left + border-top-left-radius → curve opens upward/rightward
|
||||||
|
*/
|
||||||
|
.at-branch {
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
height: 10px;
|
||||||
|
width: 19px;
|
||||||
|
border-left: 2px solid var(--card-border);
|
||||||
|
border-top: 2px solid var(--card-border);
|
||||||
|
border-top-left-radius: 8px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* depth-1: parent rail at X=9, dot left-edge at X=28 */
|
||||||
|
.at-connector[data-depth="1"] .at-branch {
|
||||||
|
left: 9px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* depth-2: parent rail at X=37, dot left-edge at X=56 */
|
||||||
|
.at-connector[data-depth="2"] .at-branch {
|
||||||
|
left: 37px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── Entry Content ── */
|
/* ── Entry Content ── */
|
||||||
|
|||||||
Reference in New Issue
Block a user