diff --git a/generated/prisma/browser.ts b/generated/prisma/browser.ts index c456817..6f0db70 100644 --- a/generated/prisma/browser.ts +++ b/generated/prisma/browser.ts @@ -42,6 +42,11 @@ export type UnifiSite = Prisma.UnifiSiteModel * */ export type Company = Prisma.CompanyModel +/** + * Model CatalogItem + * + */ +export type CatalogItem = Prisma.CatalogItemModel /** * Model CredentialType * diff --git a/generated/prisma/client.ts b/generated/prisma/client.ts index 495947d..8a1a1df 100644 --- a/generated/prisma/client.ts +++ b/generated/prisma/client.ts @@ -64,6 +64,11 @@ export type UnifiSite = Prisma.UnifiSiteModel * */ export type Company = Prisma.CompanyModel +/** + * Model CatalogItem + * + */ +export type CatalogItem = Prisma.CatalogItemModel /** * Model CredentialType * diff --git a/generated/prisma/commonInputTypes.ts b/generated/prisma/commonInputTypes.ts index 736f2a2..c70536d 100644 --- a/generated/prisma/commonInputTypes.ts +++ b/generated/prisma/commonInputTypes.ts @@ -175,6 +175,60 @@ export type IntWithAggregatesFilter<$PrismaModel = never> = { _max?: Prisma.NestedIntFilter<$PrismaModel> } +export type IntNullableFilter<$PrismaModel = never> = { + equals?: number | Prisma.IntFieldRefInput<$PrismaModel> | null + in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null + notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null + lt?: number | Prisma.IntFieldRefInput<$PrismaModel> + lte?: number | Prisma.IntFieldRefInput<$PrismaModel> + gt?: number | Prisma.IntFieldRefInput<$PrismaModel> + gte?: number | Prisma.IntFieldRefInput<$PrismaModel> + not?: Prisma.NestedIntNullableFilter<$PrismaModel> | number | null +} + +export type FloatFilter<$PrismaModel = never> = { + equals?: number | Prisma.FloatFieldRefInput<$PrismaModel> + in?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel> + notIn?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel> + lt?: number | Prisma.FloatFieldRefInput<$PrismaModel> + lte?: number | Prisma.FloatFieldRefInput<$PrismaModel> + gt?: number | Prisma.FloatFieldRefInput<$PrismaModel> + gte?: number | Prisma.FloatFieldRefInput<$PrismaModel> + not?: Prisma.NestedFloatFilter<$PrismaModel> | number +} + +export type IntNullableWithAggregatesFilter<$PrismaModel = never> = { + equals?: number | Prisma.IntFieldRefInput<$PrismaModel> | null + in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null + notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null + lt?: number | Prisma.IntFieldRefInput<$PrismaModel> + lte?: number | Prisma.IntFieldRefInput<$PrismaModel> + gt?: number | Prisma.IntFieldRefInput<$PrismaModel> + gte?: number | Prisma.IntFieldRefInput<$PrismaModel> + not?: Prisma.NestedIntNullableWithAggregatesFilter<$PrismaModel> | number | null + _count?: Prisma.NestedIntNullableFilter<$PrismaModel> + _avg?: Prisma.NestedFloatNullableFilter<$PrismaModel> + _sum?: Prisma.NestedIntNullableFilter<$PrismaModel> + _min?: Prisma.NestedIntNullableFilter<$PrismaModel> + _max?: Prisma.NestedIntNullableFilter<$PrismaModel> +} + +export type FloatWithAggregatesFilter<$PrismaModel = never> = { + equals?: number | Prisma.FloatFieldRefInput<$PrismaModel> + in?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel> + notIn?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel> + lt?: number | Prisma.FloatFieldRefInput<$PrismaModel> + lte?: number | Prisma.FloatFieldRefInput<$PrismaModel> + gt?: number | Prisma.FloatFieldRefInput<$PrismaModel> + gte?: number | Prisma.FloatFieldRefInput<$PrismaModel> + not?: Prisma.NestedFloatWithAggregatesFilter<$PrismaModel> | number + _count?: Prisma.NestedIntFilter<$PrismaModel> + _avg?: Prisma.NestedFloatFilter<$PrismaModel> + _sum?: Prisma.NestedFloatFilter<$PrismaModel> + _min?: Prisma.NestedFloatFilter<$PrismaModel> + _max?: Prisma.NestedFloatFilter<$PrismaModel> +} + export type JsonFilter<$PrismaModel = never> = | Prisma.PatchUndefined< Prisma.Either>, Exclude>, 'path'>>, @@ -400,6 +454,49 @@ export type NestedFloatFilter<$PrismaModel = never> = { not?: Prisma.NestedFloatFilter<$PrismaModel> | number } +export type NestedIntNullableWithAggregatesFilter<$PrismaModel = never> = { + equals?: number | Prisma.IntFieldRefInput<$PrismaModel> | null + in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null + notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null + lt?: number | Prisma.IntFieldRefInput<$PrismaModel> + lte?: number | Prisma.IntFieldRefInput<$PrismaModel> + gt?: number | Prisma.IntFieldRefInput<$PrismaModel> + gte?: number | Prisma.IntFieldRefInput<$PrismaModel> + not?: Prisma.NestedIntNullableWithAggregatesFilter<$PrismaModel> | number | null + _count?: Prisma.NestedIntNullableFilter<$PrismaModel> + _avg?: Prisma.NestedFloatNullableFilter<$PrismaModel> + _sum?: Prisma.NestedIntNullableFilter<$PrismaModel> + _min?: Prisma.NestedIntNullableFilter<$PrismaModel> + _max?: Prisma.NestedIntNullableFilter<$PrismaModel> +} + +export type NestedFloatNullableFilter<$PrismaModel = never> = { + equals?: number | Prisma.FloatFieldRefInput<$PrismaModel> | null + in?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel> | null + notIn?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel> | null + lt?: number | Prisma.FloatFieldRefInput<$PrismaModel> + lte?: number | Prisma.FloatFieldRefInput<$PrismaModel> + gt?: number | Prisma.FloatFieldRefInput<$PrismaModel> + gte?: number | Prisma.FloatFieldRefInput<$PrismaModel> + not?: Prisma.NestedFloatNullableFilter<$PrismaModel> | number | null +} + +export type NestedFloatWithAggregatesFilter<$PrismaModel = never> = { + equals?: number | Prisma.FloatFieldRefInput<$PrismaModel> + in?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel> + notIn?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel> + lt?: number | Prisma.FloatFieldRefInput<$PrismaModel> + lte?: number | Prisma.FloatFieldRefInput<$PrismaModel> + gt?: number | Prisma.FloatFieldRefInput<$PrismaModel> + gte?: number | Prisma.FloatFieldRefInput<$PrismaModel> + not?: Prisma.NestedFloatWithAggregatesFilter<$PrismaModel> | number + _count?: Prisma.NestedIntFilter<$PrismaModel> + _avg?: Prisma.NestedFloatFilter<$PrismaModel> + _sum?: Prisma.NestedFloatFilter<$PrismaModel> + _min?: Prisma.NestedFloatFilter<$PrismaModel> + _max?: Prisma.NestedFloatFilter<$PrismaModel> +} + export type NestedJsonFilter<$PrismaModel = never> = | Prisma.PatchUndefined< Prisma.Either>, Exclude>, 'path'>>, diff --git a/generated/prisma/internal/class.ts b/generated/prisma/internal/class.ts index 0b83420..121bc22 100644 --- a/generated/prisma/internal/class.ts +++ b/generated/prisma/internal/class.ts @@ -20,7 +20,7 @@ const config: runtime.GetPrismaClientConfig = { "clientVersion": "7.3.0", "engineVersion": "9d6ad21cbbceab97458517b147a6a09ff43aa735", "activeProvider": "postgresql", - "inlineSchema": "// This is your Prisma schema file,\n// learn more about it in the docs: https://pris.ly/d/prisma-schema\n\n// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?\n// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init\n\ngenerator client {\n provider = \"prisma-client\"\n output = \"../generated/prisma\"\n}\n\ndatasource db {\n provider = \"postgresql\"\n}\n\nmodel Session {\n id String @id @default(uuid())\n sessionKey String @unique @default(cuid())\n userId String\n expires DateTime\n refreshTokenGenerated Boolean @default(false)\n refreshedAt DateTime?\n invalidatedAt DateTime?\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n}\n\nmodel User {\n id String @id @default(cuid())\n roles Role[]\n permissions String?\n login String @unique\n name String?\n email String @unique\n emailVerified DateTime?\n image String?\n\n userId String @unique\n token String?\n\n sessions Session[]\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel Role {\n id String @id @default(uuid())\n title String\n moniker String @unique // e.g. admin, super_admin, moderator\n\n permissions String\n users User[]\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel UnifiSite {\n id String @id @default(cuid())\n name String\n\n siteId String @unique\n\n companyId String?\n company Company? @relation(fields: [companyId], references: [id])\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel Company {\n id String @id @default(cuid())\n name String\n\n cw_CompanyId Int @unique\n cw_Identifier String @unique\n\n credentials Credential[]\n unifiSites UnifiSite[]\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel CredentialType {\n id String @id @default(cuid())\n name String @unique\n\n permissionScope String\n icon String?\n fields Json\n\n credentials Credential[]\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel SecureValue {\n id String @id @default(cuid())\n name String\n\n content String // Encrypted content\n hash String // Hash of the original content for integrity verification and Search\n\n credentialId String\n credential Credential @relation(fields: [credentialId], references: [id], onDelete: Cascade)\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel Credential {\n id String @id @default(cuid())\n name String\n notes String?\n subCredentialOfId String?\n subCredentialOf Credential? @relation(\"SubCredentials\", fields: [subCredentialOfId], references: [id], onDelete: Cascade)\n subCredentials Credential[] @relation(\"SubCredentials\")\n\n typeId String\n type CredentialType @relation(fields: [typeId], references: [id], onDelete: Cascade)\n\n fields Json\n\n companyId String\n company Company @relation(fields: [companyId], references: [id], onDelete: Cascade)\n\n securevalues SecureValue[]\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n", + "inlineSchema": "// This is your Prisma schema file,\n// learn more about it in the docs: https://pris.ly/d/prisma-schema\n\n// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?\n// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init\n\ngenerator client {\n provider = \"prisma-client\"\n output = \"../generated/prisma\"\n}\n\ndatasource db {\n provider = \"postgresql\"\n}\n\nmodel Session {\n id String @id @default(uuid())\n sessionKey String @unique @default(cuid())\n userId String\n expires DateTime\n refreshTokenGenerated Boolean @default(false)\n refreshedAt DateTime?\n invalidatedAt DateTime?\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n}\n\nmodel User {\n id String @id @default(cuid())\n roles Role[]\n permissions String?\n login String @unique\n name String?\n email String @unique\n emailVerified DateTime?\n image String?\n\n userId String @unique\n token String?\n\n sessions Session[]\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel Role {\n id String @id @default(uuid())\n title String\n moniker String @unique // e.g. admin, super_admin, moderator\n\n permissions String\n users User[]\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel UnifiSite {\n id String @id @default(cuid())\n name String\n\n siteId String @unique\n\n companyId String?\n company Company? @relation(fields: [companyId], references: [id])\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel Company {\n id String @id @default(cuid())\n name String\n\n cw_CompanyId Int @unique\n cw_Identifier String @unique\n\n credentials Credential[]\n unifiSites UnifiSite[]\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel CatalogItem {\n id String @id @default(cuid())\n cwCatalogId Int @unique\n name String\n description String?\n customerDescription String?\n internalNotes String?\n\n linkedItems CatalogItem[] @relation(\"LinkedItems\")\n linkedTo CatalogItem[] @relation(\"LinkedItems\")\n\n manufacturer String?\n manufactureCwId Int?\n\n partNumber String?\n\n vendorName String?\n vendorSku String?\n vendorCwId Int?\n\n price Float\n cost Float\n\n inactive Boolean @default(false)\n salesTaxable Boolean @default(true)\n\n onHand Int @default(0)\n cwLastUpdated DateTime?\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel CredentialType {\n id String @id @default(cuid())\n name String @unique\n\n permissionScope String\n icon String?\n fields Json\n\n credentials Credential[]\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel SecureValue {\n id String @id @default(cuid())\n name String\n\n content String // Encrypted content\n hash String // Hash of the original content for integrity verification and Search\n\n credentialId String\n credential Credential @relation(fields: [credentialId], references: [id], onDelete: Cascade)\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel Credential {\n id String @id @default(cuid())\n name String\n notes String?\n subCredentialOfId String?\n subCredentialOf Credential? @relation(\"SubCredentials\", fields: [subCredentialOfId], references: [id], onDelete: Cascade)\n subCredentials Credential[] @relation(\"SubCredentials\")\n\n typeId String\n type CredentialType @relation(fields: [typeId], references: [id], onDelete: Cascade)\n\n fields Json\n\n companyId String\n company Company @relation(fields: [companyId], references: [id], onDelete: Cascade)\n\n securevalues SecureValue[]\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n", "runtimeDataModel": { "models": {}, "enums": {}, @@ -28,7 +28,7 @@ const config: runtime.GetPrismaClientConfig = { } } -config.runtimeDataModel = JSON.parse("{\"models\":{\"Session\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"sessionKey\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"expires\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"refreshTokenGenerated\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"refreshedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"invalidatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"SessionToUser\"}],\"dbName\":null},\"User\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"roles\",\"kind\":\"object\",\"type\":\"Role\",\"relationName\":\"RoleToUser\"},{\"name\":\"permissions\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"login\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"email\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"emailVerified\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"image\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"token\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"sessions\",\"kind\":\"object\",\"type\":\"Session\",\"relationName\":\"SessionToUser\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"Role\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"title\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"moniker\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"permissions\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"users\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"RoleToUser\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"UnifiSite\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"siteId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"companyId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"company\",\"kind\":\"object\",\"type\":\"Company\",\"relationName\":\"CompanyToUnifiSite\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"Company\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"cw_CompanyId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"cw_Identifier\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"credentials\",\"kind\":\"object\",\"type\":\"Credential\",\"relationName\":\"CompanyToCredential\"},{\"name\":\"unifiSites\",\"kind\":\"object\",\"type\":\"UnifiSite\",\"relationName\":\"CompanyToUnifiSite\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"CredentialType\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"permissionScope\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"icon\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"fields\",\"kind\":\"scalar\",\"type\":\"Json\"},{\"name\":\"credentials\",\"kind\":\"object\",\"type\":\"Credential\",\"relationName\":\"CredentialToCredentialType\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"SecureValue\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"content\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"hash\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"credentialId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"credential\",\"kind\":\"object\",\"type\":\"Credential\",\"relationName\":\"CredentialToSecureValue\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"Credential\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"notes\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"subCredentialOfId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"subCredentialOf\",\"kind\":\"object\",\"type\":\"Credential\",\"relationName\":\"SubCredentials\"},{\"name\":\"subCredentials\",\"kind\":\"object\",\"type\":\"Credential\",\"relationName\":\"SubCredentials\"},{\"name\":\"typeId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"type\",\"kind\":\"object\",\"type\":\"CredentialType\",\"relationName\":\"CredentialToCredentialType\"},{\"name\":\"fields\",\"kind\":\"scalar\",\"type\":\"Json\"},{\"name\":\"companyId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"company\",\"kind\":\"object\",\"type\":\"Company\",\"relationName\":\"CompanyToCredential\"},{\"name\":\"securevalues\",\"kind\":\"object\",\"type\":\"SecureValue\",\"relationName\":\"CredentialToSecureValue\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null}},\"enums\":{},\"types\":{}}") +config.runtimeDataModel = JSON.parse("{\"models\":{\"Session\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"sessionKey\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"expires\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"refreshTokenGenerated\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"refreshedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"invalidatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"SessionToUser\"}],\"dbName\":null},\"User\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"roles\",\"kind\":\"object\",\"type\":\"Role\",\"relationName\":\"RoleToUser\"},{\"name\":\"permissions\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"login\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"email\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"emailVerified\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"image\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"token\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"sessions\",\"kind\":\"object\",\"type\":\"Session\",\"relationName\":\"SessionToUser\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"Role\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"title\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"moniker\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"permissions\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"users\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"RoleToUser\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"UnifiSite\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"siteId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"companyId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"company\",\"kind\":\"object\",\"type\":\"Company\",\"relationName\":\"CompanyToUnifiSite\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"Company\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"cw_CompanyId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"cw_Identifier\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"credentials\",\"kind\":\"object\",\"type\":\"Credential\",\"relationName\":\"CompanyToCredential\"},{\"name\":\"unifiSites\",\"kind\":\"object\",\"type\":\"UnifiSite\",\"relationName\":\"CompanyToUnifiSite\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"CatalogItem\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"cwCatalogId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"description\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"customerDescription\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"internalNotes\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"linkedItems\",\"kind\":\"object\",\"type\":\"CatalogItem\",\"relationName\":\"LinkedItems\"},{\"name\":\"linkedTo\",\"kind\":\"object\",\"type\":\"CatalogItem\",\"relationName\":\"LinkedItems\"},{\"name\":\"manufacturer\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"manufactureCwId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"partNumber\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"vendorName\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"vendorSku\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"vendorCwId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"price\",\"kind\":\"scalar\",\"type\":\"Float\"},{\"name\":\"cost\",\"kind\":\"scalar\",\"type\":\"Float\"},{\"name\":\"inactive\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"salesTaxable\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"onHand\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"cwLastUpdated\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"CredentialType\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"permissionScope\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"icon\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"fields\",\"kind\":\"scalar\",\"type\":\"Json\"},{\"name\":\"credentials\",\"kind\":\"object\",\"type\":\"Credential\",\"relationName\":\"CredentialToCredentialType\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"SecureValue\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"content\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"hash\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"credentialId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"credential\",\"kind\":\"object\",\"type\":\"Credential\",\"relationName\":\"CredentialToSecureValue\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"Credential\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"notes\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"subCredentialOfId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"subCredentialOf\",\"kind\":\"object\",\"type\":\"Credential\",\"relationName\":\"SubCredentials\"},{\"name\":\"subCredentials\",\"kind\":\"object\",\"type\":\"Credential\",\"relationName\":\"SubCredentials\"},{\"name\":\"typeId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"type\",\"kind\":\"object\",\"type\":\"CredentialType\",\"relationName\":\"CredentialToCredentialType\"},{\"name\":\"fields\",\"kind\":\"scalar\",\"type\":\"Json\"},{\"name\":\"companyId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"company\",\"kind\":\"object\",\"type\":\"Company\",\"relationName\":\"CompanyToCredential\"},{\"name\":\"securevalues\",\"kind\":\"object\",\"type\":\"SecureValue\",\"relationName\":\"CredentialToSecureValue\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null}},\"enums\":{},\"types\":{}}") async function decodeBase64AsWasm(wasmBase64: string): Promise { const { Buffer } = await import('node:buffer') @@ -226,6 +226,16 @@ export interface PrismaClient< */ get company(): Prisma.CompanyDelegate; + /** + * `prisma.catalogItem`: Exposes CRUD operations for the **CatalogItem** model. + * Example usage: + * ```ts + * // Fetch zero or more CatalogItems + * const catalogItems = await prisma.catalogItem.findMany() + * ``` + */ + get catalogItem(): Prisma.CatalogItemDelegate; + /** * `prisma.credentialType`: Exposes CRUD operations for the **CredentialType** model. * Example usage: diff --git a/generated/prisma/internal/prismaNamespace.ts b/generated/prisma/internal/prismaNamespace.ts index e67bbf4..41c828f 100644 --- a/generated/prisma/internal/prismaNamespace.ts +++ b/generated/prisma/internal/prismaNamespace.ts @@ -389,6 +389,7 @@ export const ModelName = { Role: 'Role', UnifiSite: 'UnifiSite', Company: 'Company', + CatalogItem: 'CatalogItem', CredentialType: 'CredentialType', SecureValue: 'SecureValue', Credential: 'Credential' @@ -407,7 +408,7 @@ export type TypeMap + fields: Prisma.CatalogItemFieldRefs + operations: { + findUnique: { + args: Prisma.CatalogItemFindUniqueArgs + result: runtime.Types.Utils.PayloadToResult | null + } + findUniqueOrThrow: { + args: Prisma.CatalogItemFindUniqueOrThrowArgs + result: runtime.Types.Utils.PayloadToResult + } + findFirst: { + args: Prisma.CatalogItemFindFirstArgs + result: runtime.Types.Utils.PayloadToResult | null + } + findFirstOrThrow: { + args: Prisma.CatalogItemFindFirstOrThrowArgs + result: runtime.Types.Utils.PayloadToResult + } + findMany: { + args: Prisma.CatalogItemFindManyArgs + result: runtime.Types.Utils.PayloadToResult[] + } + create: { + args: Prisma.CatalogItemCreateArgs + result: runtime.Types.Utils.PayloadToResult + } + createMany: { + args: Prisma.CatalogItemCreateManyArgs + result: BatchPayload + } + createManyAndReturn: { + args: Prisma.CatalogItemCreateManyAndReturnArgs + result: runtime.Types.Utils.PayloadToResult[] + } + delete: { + args: Prisma.CatalogItemDeleteArgs + result: runtime.Types.Utils.PayloadToResult + } + update: { + args: Prisma.CatalogItemUpdateArgs + result: runtime.Types.Utils.PayloadToResult + } + deleteMany: { + args: Prisma.CatalogItemDeleteManyArgs + result: BatchPayload + } + updateMany: { + args: Prisma.CatalogItemUpdateManyArgs + result: BatchPayload + } + updateManyAndReturn: { + args: Prisma.CatalogItemUpdateManyAndReturnArgs + result: runtime.Types.Utils.PayloadToResult[] + } + upsert: { + args: Prisma.CatalogItemUpsertArgs + result: runtime.Types.Utils.PayloadToResult + } + aggregate: { + args: Prisma.CatalogItemAggregateArgs + result: runtime.Types.Utils.Optional + } + groupBy: { + args: Prisma.CatalogItemGroupByArgs + result: runtime.Types.Utils.Optional[] + } + count: { + args: Prisma.CatalogItemCountArgs + result: runtime.Types.Utils.Optional | number + } + } + } CredentialType: { payload: Prisma.$CredentialTypePayload fields: Prisma.CredentialTypeFieldRefs @@ -1108,6 +1183,32 @@ export const CompanyScalarFieldEnum = { export type CompanyScalarFieldEnum = (typeof CompanyScalarFieldEnum)[keyof typeof CompanyScalarFieldEnum] +export const CatalogItemScalarFieldEnum = { + id: 'id', + cwCatalogId: 'cwCatalogId', + name: 'name', + description: 'description', + customerDescription: 'customerDescription', + internalNotes: 'internalNotes', + manufacturer: 'manufacturer', + manufactureCwId: 'manufactureCwId', + partNumber: 'partNumber', + vendorName: 'vendorName', + vendorSku: 'vendorSku', + vendorCwId: 'vendorCwId', + price: 'price', + cost: 'cost', + inactive: 'inactive', + salesTaxable: 'salesTaxable', + onHand: 'onHand', + cwLastUpdated: 'cwLastUpdated', + createdAt: 'createdAt', + updatedAt: 'updatedAt' +} as const + +export type CatalogItemScalarFieldEnum = (typeof CatalogItemScalarFieldEnum)[keyof typeof CatalogItemScalarFieldEnum] + + export const CredentialTypeScalarFieldEnum = { id: 'id', name: 'name', @@ -1244,20 +1345,6 @@ export type ListIntFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, -/** - * Reference to a field of type 'Json' - */ -export type JsonFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'Json'> - - - -/** - * Reference to a field of type 'QueryMode' - */ -export type EnumQueryModeFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'QueryMode'> - - - /** * Reference to a field of type 'Float' */ @@ -1271,6 +1358,20 @@ export type FloatFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, ' export type ListFloatFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'Float[]'> + +/** + * Reference to a field of type 'Json' + */ +export type JsonFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'Json'> + + + +/** + * Reference to a field of type 'QueryMode' + */ +export type EnumQueryModeFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'QueryMode'> + + /** * Batch Payload for updateMany & deleteMany & createMany */ @@ -1371,6 +1472,7 @@ export type GlobalOmitConfig = { role?: Prisma.RoleOmit unifiSite?: Prisma.UnifiSiteOmit company?: Prisma.CompanyOmit + catalogItem?: Prisma.CatalogItemOmit credentialType?: Prisma.CredentialTypeOmit secureValue?: Prisma.SecureValueOmit credential?: Prisma.CredentialOmit diff --git a/generated/prisma/internal/prismaNamespaceBrowser.ts b/generated/prisma/internal/prismaNamespaceBrowser.ts index 2951e43..226cc3c 100644 --- a/generated/prisma/internal/prismaNamespaceBrowser.ts +++ b/generated/prisma/internal/prismaNamespaceBrowser.ts @@ -56,6 +56,7 @@ export const ModelName = { Role: 'Role', UnifiSite: 'UnifiSite', Company: 'Company', + CatalogItem: 'CatalogItem', CredentialType: 'CredentialType', SecureValue: 'SecureValue', Credential: 'Credential' @@ -143,6 +144,32 @@ export const CompanyScalarFieldEnum = { export type CompanyScalarFieldEnum = (typeof CompanyScalarFieldEnum)[keyof typeof CompanyScalarFieldEnum] +export const CatalogItemScalarFieldEnum = { + id: 'id', + cwCatalogId: 'cwCatalogId', + name: 'name', + description: 'description', + customerDescription: 'customerDescription', + internalNotes: 'internalNotes', + manufacturer: 'manufacturer', + manufactureCwId: 'manufactureCwId', + partNumber: 'partNumber', + vendorName: 'vendorName', + vendorSku: 'vendorSku', + vendorCwId: 'vendorCwId', + price: 'price', + cost: 'cost', + inactive: 'inactive', + salesTaxable: 'salesTaxable', + onHand: 'onHand', + cwLastUpdated: 'cwLastUpdated', + createdAt: 'createdAt', + updatedAt: 'updatedAt' +} as const + +export type CatalogItemScalarFieldEnum = (typeof CatalogItemScalarFieldEnum)[keyof typeof CatalogItemScalarFieldEnum] + + export const CredentialTypeScalarFieldEnum = { id: 'id', name: 'name', diff --git a/generated/prisma/models.ts b/generated/prisma/models.ts index da02256..031d062 100644 --- a/generated/prisma/models.ts +++ b/generated/prisma/models.ts @@ -13,6 +13,7 @@ export type * from './models/User.ts' export type * from './models/Role.ts' export type * from './models/UnifiSite.ts' export type * from './models/Company.ts' +export type * from './models/CatalogItem.ts' export type * from './models/CredentialType.ts' export type * from './models/SecureValue.ts' export type * from './models/Credential.ts' diff --git a/generated/prisma/models/CatalogItem.ts b/generated/prisma/models/CatalogItem.ts new file mode 100644 index 0000000..274cf69 --- /dev/null +++ b/generated/prisma/models/CatalogItem.ts @@ -0,0 +1,2201 @@ + +/* !!! This is code generated by Prisma. Do not edit directly. !!! */ +/* eslint-disable */ +// biome-ignore-all lint: generated file +// @ts-nocheck +/* + * This file exports the `CatalogItem` model and its related types. + * + * 🟢 You can import this file directly. + */ +import type * as runtime from "@prisma/client/runtime/client" +import type * as $Enums from "../enums.ts" +import type * as Prisma from "../internal/prismaNamespace.ts" + +/** + * Model CatalogItem + * + */ +export type CatalogItemModel = runtime.Types.Result.DefaultSelection + +export type AggregateCatalogItem = { + _count: CatalogItemCountAggregateOutputType | null + _avg: CatalogItemAvgAggregateOutputType | null + _sum: CatalogItemSumAggregateOutputType | null + _min: CatalogItemMinAggregateOutputType | null + _max: CatalogItemMaxAggregateOutputType | null +} + +export type CatalogItemAvgAggregateOutputType = { + cwCatalogId: number | null + manufactureCwId: number | null + vendorCwId: number | null + price: number | null + cost: number | null + onHand: number | null +} + +export type CatalogItemSumAggregateOutputType = { + cwCatalogId: number | null + manufactureCwId: number | null + vendorCwId: number | null + price: number | null + cost: number | null + onHand: number | null +} + +export type CatalogItemMinAggregateOutputType = { + id: string | null + cwCatalogId: number | null + name: string | null + description: string | null + customerDescription: string | null + internalNotes: string | null + manufacturer: string | null + manufactureCwId: number | null + partNumber: string | null + vendorName: string | null + vendorSku: string | null + vendorCwId: number | null + price: number | null + cost: number | null + inactive: boolean | null + salesTaxable: boolean | null + onHand: number | null + cwLastUpdated: Date | null + createdAt: Date | null + updatedAt: Date | null +} + +export type CatalogItemMaxAggregateOutputType = { + id: string | null + cwCatalogId: number | null + name: string | null + description: string | null + customerDescription: string | null + internalNotes: string | null + manufacturer: string | null + manufactureCwId: number | null + partNumber: string | null + vendorName: string | null + vendorSku: string | null + vendorCwId: number | null + price: number | null + cost: number | null + inactive: boolean | null + salesTaxable: boolean | null + onHand: number | null + cwLastUpdated: Date | null + createdAt: Date | null + updatedAt: Date | null +} + +export type CatalogItemCountAggregateOutputType = { + id: number + cwCatalogId: number + name: number + description: number + customerDescription: number + internalNotes: number + manufacturer: number + manufactureCwId: number + partNumber: number + vendorName: number + vendorSku: number + vendorCwId: number + price: number + cost: number + inactive: number + salesTaxable: number + onHand: number + cwLastUpdated: number + createdAt: number + updatedAt: number + _all: number +} + + +export type CatalogItemAvgAggregateInputType = { + cwCatalogId?: true + manufactureCwId?: true + vendorCwId?: true + price?: true + cost?: true + onHand?: true +} + +export type CatalogItemSumAggregateInputType = { + cwCatalogId?: true + manufactureCwId?: true + vendorCwId?: true + price?: true + cost?: true + onHand?: true +} + +export type CatalogItemMinAggregateInputType = { + id?: true + cwCatalogId?: true + name?: true + description?: true + customerDescription?: true + internalNotes?: true + manufacturer?: true + manufactureCwId?: true + partNumber?: true + vendorName?: true + vendorSku?: true + vendorCwId?: true + price?: true + cost?: true + inactive?: true + salesTaxable?: true + onHand?: true + cwLastUpdated?: true + createdAt?: true + updatedAt?: true +} + +export type CatalogItemMaxAggregateInputType = { + id?: true + cwCatalogId?: true + name?: true + description?: true + customerDescription?: true + internalNotes?: true + manufacturer?: true + manufactureCwId?: true + partNumber?: true + vendorName?: true + vendorSku?: true + vendorCwId?: true + price?: true + cost?: true + inactive?: true + salesTaxable?: true + onHand?: true + cwLastUpdated?: true + createdAt?: true + updatedAt?: true +} + +export type CatalogItemCountAggregateInputType = { + id?: true + cwCatalogId?: true + name?: true + description?: true + customerDescription?: true + internalNotes?: true + manufacturer?: true + manufactureCwId?: true + partNumber?: true + vendorName?: true + vendorSku?: true + vendorCwId?: true + price?: true + cost?: true + inactive?: true + salesTaxable?: true + onHand?: true + cwLastUpdated?: true + createdAt?: true + updatedAt?: true + _all?: true +} + +export type CatalogItemAggregateArgs = { + /** + * Filter which CatalogItem to aggregate. + */ + where?: Prisma.CatalogItemWhereInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/sorting Sorting Docs} + * + * Determine the order of CatalogItems to fetch. + */ + orderBy?: Prisma.CatalogItemOrderByWithRelationInput | Prisma.CatalogItemOrderByWithRelationInput[] + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination#cursor-based-pagination Cursor Docs} + * + * Sets the start position + */ + cursor?: Prisma.CatalogItemWhereUniqueInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Take `±n` CatalogItems from the position of the cursor. + */ + take?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Skip the first `n` CatalogItems. + */ + skip?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/aggregations Aggregation Docs} + * + * Count returned CatalogItems + **/ + _count?: true | CatalogItemCountAggregateInputType + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/aggregations Aggregation Docs} + * + * Select which fields to average + **/ + _avg?: CatalogItemAvgAggregateInputType + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/aggregations Aggregation Docs} + * + * Select which fields to sum + **/ + _sum?: CatalogItemSumAggregateInputType + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/aggregations Aggregation Docs} + * + * Select which fields to find the minimum value + **/ + _min?: CatalogItemMinAggregateInputType + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/aggregations Aggregation Docs} + * + * Select which fields to find the maximum value + **/ + _max?: CatalogItemMaxAggregateInputType +} + +export type GetCatalogItemAggregateType = { + [P in keyof T & keyof AggregateCatalogItem]: P extends '_count' | 'count' + ? T[P] extends true + ? number + : Prisma.GetScalarType + : Prisma.GetScalarType +} + + + + +export type CatalogItemGroupByArgs = { + where?: Prisma.CatalogItemWhereInput + orderBy?: Prisma.CatalogItemOrderByWithAggregationInput | Prisma.CatalogItemOrderByWithAggregationInput[] + by: Prisma.CatalogItemScalarFieldEnum[] | Prisma.CatalogItemScalarFieldEnum + having?: Prisma.CatalogItemScalarWhereWithAggregatesInput + take?: number + skip?: number + _count?: CatalogItemCountAggregateInputType | true + _avg?: CatalogItemAvgAggregateInputType + _sum?: CatalogItemSumAggregateInputType + _min?: CatalogItemMinAggregateInputType + _max?: CatalogItemMaxAggregateInputType +} + +export type CatalogItemGroupByOutputType = { + id: string + cwCatalogId: number + name: string + description: string | null + customerDescription: string | null + internalNotes: string | null + manufacturer: string | null + manufactureCwId: number | null + partNumber: string | null + vendorName: string | null + vendorSku: string | null + vendorCwId: number | null + price: number + cost: number + inactive: boolean + salesTaxable: boolean + onHand: number + cwLastUpdated: Date | null + createdAt: Date + updatedAt: Date + _count: CatalogItemCountAggregateOutputType | null + _avg: CatalogItemAvgAggregateOutputType | null + _sum: CatalogItemSumAggregateOutputType | null + _min: CatalogItemMinAggregateOutputType | null + _max: CatalogItemMaxAggregateOutputType | null +} + +type GetCatalogItemGroupByPayload = Prisma.PrismaPromise< + Array< + Prisma.PickEnumerable & + { + [P in ((keyof T) & (keyof CatalogItemGroupByOutputType))]: P extends '_count' + ? T[P] extends boolean + ? number + : Prisma.GetScalarType + : Prisma.GetScalarType + } + > + > + + + +export type CatalogItemWhereInput = { + AND?: Prisma.CatalogItemWhereInput | Prisma.CatalogItemWhereInput[] + OR?: Prisma.CatalogItemWhereInput[] + NOT?: Prisma.CatalogItemWhereInput | Prisma.CatalogItemWhereInput[] + id?: Prisma.StringFilter<"CatalogItem"> | string + cwCatalogId?: Prisma.IntFilter<"CatalogItem"> | number + name?: Prisma.StringFilter<"CatalogItem"> | string + description?: Prisma.StringNullableFilter<"CatalogItem"> | string | null + customerDescription?: Prisma.StringNullableFilter<"CatalogItem"> | string | null + internalNotes?: Prisma.StringNullableFilter<"CatalogItem"> | string | null + manufacturer?: Prisma.StringNullableFilter<"CatalogItem"> | string | null + manufactureCwId?: Prisma.IntNullableFilter<"CatalogItem"> | number | null + partNumber?: Prisma.StringNullableFilter<"CatalogItem"> | string | null + vendorName?: Prisma.StringNullableFilter<"CatalogItem"> | string | null + vendorSku?: Prisma.StringNullableFilter<"CatalogItem"> | string | null + vendorCwId?: Prisma.IntNullableFilter<"CatalogItem"> | number | null + price?: Prisma.FloatFilter<"CatalogItem"> | number + cost?: Prisma.FloatFilter<"CatalogItem"> | number + inactive?: Prisma.BoolFilter<"CatalogItem"> | boolean + salesTaxable?: Prisma.BoolFilter<"CatalogItem"> | boolean + onHand?: Prisma.IntFilter<"CatalogItem"> | number + cwLastUpdated?: Prisma.DateTimeNullableFilter<"CatalogItem"> | Date | string | null + createdAt?: Prisma.DateTimeFilter<"CatalogItem"> | Date | string + updatedAt?: Prisma.DateTimeFilter<"CatalogItem"> | Date | string + linkedItems?: Prisma.CatalogItemListRelationFilter + linkedTo?: Prisma.CatalogItemListRelationFilter +} + +export type CatalogItemOrderByWithRelationInput = { + id?: Prisma.SortOrder + cwCatalogId?: Prisma.SortOrder + name?: Prisma.SortOrder + description?: Prisma.SortOrderInput | Prisma.SortOrder + customerDescription?: Prisma.SortOrderInput | Prisma.SortOrder + internalNotes?: Prisma.SortOrderInput | Prisma.SortOrder + manufacturer?: Prisma.SortOrderInput | Prisma.SortOrder + manufactureCwId?: Prisma.SortOrderInput | Prisma.SortOrder + partNumber?: Prisma.SortOrderInput | Prisma.SortOrder + vendorName?: Prisma.SortOrderInput | Prisma.SortOrder + vendorSku?: Prisma.SortOrderInput | Prisma.SortOrder + vendorCwId?: Prisma.SortOrderInput | Prisma.SortOrder + price?: Prisma.SortOrder + cost?: Prisma.SortOrder + inactive?: Prisma.SortOrder + salesTaxable?: Prisma.SortOrder + onHand?: Prisma.SortOrder + cwLastUpdated?: Prisma.SortOrderInput | Prisma.SortOrder + createdAt?: Prisma.SortOrder + updatedAt?: Prisma.SortOrder + linkedItems?: Prisma.CatalogItemOrderByRelationAggregateInput + linkedTo?: Prisma.CatalogItemOrderByRelationAggregateInput +} + +export type CatalogItemWhereUniqueInput = Prisma.AtLeast<{ + id?: string + cwCatalogId?: number + AND?: Prisma.CatalogItemWhereInput | Prisma.CatalogItemWhereInput[] + OR?: Prisma.CatalogItemWhereInput[] + NOT?: Prisma.CatalogItemWhereInput | Prisma.CatalogItemWhereInput[] + name?: Prisma.StringFilter<"CatalogItem"> | string + description?: Prisma.StringNullableFilter<"CatalogItem"> | string | null + customerDescription?: Prisma.StringNullableFilter<"CatalogItem"> | string | null + internalNotes?: Prisma.StringNullableFilter<"CatalogItem"> | string | null + manufacturer?: Prisma.StringNullableFilter<"CatalogItem"> | string | null + manufactureCwId?: Prisma.IntNullableFilter<"CatalogItem"> | number | null + partNumber?: Prisma.StringNullableFilter<"CatalogItem"> | string | null + vendorName?: Prisma.StringNullableFilter<"CatalogItem"> | string | null + vendorSku?: Prisma.StringNullableFilter<"CatalogItem"> | string | null + vendorCwId?: Prisma.IntNullableFilter<"CatalogItem"> | number | null + price?: Prisma.FloatFilter<"CatalogItem"> | number + cost?: Prisma.FloatFilter<"CatalogItem"> | number + inactive?: Prisma.BoolFilter<"CatalogItem"> | boolean + salesTaxable?: Prisma.BoolFilter<"CatalogItem"> | boolean + onHand?: Prisma.IntFilter<"CatalogItem"> | number + cwLastUpdated?: Prisma.DateTimeNullableFilter<"CatalogItem"> | Date | string | null + createdAt?: Prisma.DateTimeFilter<"CatalogItem"> | Date | string + updatedAt?: Prisma.DateTimeFilter<"CatalogItem"> | Date | string + linkedItems?: Prisma.CatalogItemListRelationFilter + linkedTo?: Prisma.CatalogItemListRelationFilter +}, "id" | "cwCatalogId"> + +export type CatalogItemOrderByWithAggregationInput = { + id?: Prisma.SortOrder + cwCatalogId?: Prisma.SortOrder + name?: Prisma.SortOrder + description?: Prisma.SortOrderInput | Prisma.SortOrder + customerDescription?: Prisma.SortOrderInput | Prisma.SortOrder + internalNotes?: Prisma.SortOrderInput | Prisma.SortOrder + manufacturer?: Prisma.SortOrderInput | Prisma.SortOrder + manufactureCwId?: Prisma.SortOrderInput | Prisma.SortOrder + partNumber?: Prisma.SortOrderInput | Prisma.SortOrder + vendorName?: Prisma.SortOrderInput | Prisma.SortOrder + vendorSku?: Prisma.SortOrderInput | Prisma.SortOrder + vendorCwId?: Prisma.SortOrderInput | Prisma.SortOrder + price?: Prisma.SortOrder + cost?: Prisma.SortOrder + inactive?: Prisma.SortOrder + salesTaxable?: Prisma.SortOrder + onHand?: Prisma.SortOrder + cwLastUpdated?: Prisma.SortOrderInput | Prisma.SortOrder + createdAt?: Prisma.SortOrder + updatedAt?: Prisma.SortOrder + _count?: Prisma.CatalogItemCountOrderByAggregateInput + _avg?: Prisma.CatalogItemAvgOrderByAggregateInput + _max?: Prisma.CatalogItemMaxOrderByAggregateInput + _min?: Prisma.CatalogItemMinOrderByAggregateInput + _sum?: Prisma.CatalogItemSumOrderByAggregateInput +} + +export type CatalogItemScalarWhereWithAggregatesInput = { + AND?: Prisma.CatalogItemScalarWhereWithAggregatesInput | Prisma.CatalogItemScalarWhereWithAggregatesInput[] + OR?: Prisma.CatalogItemScalarWhereWithAggregatesInput[] + NOT?: Prisma.CatalogItemScalarWhereWithAggregatesInput | Prisma.CatalogItemScalarWhereWithAggregatesInput[] + id?: Prisma.StringWithAggregatesFilter<"CatalogItem"> | string + cwCatalogId?: Prisma.IntWithAggregatesFilter<"CatalogItem"> | number + name?: Prisma.StringWithAggregatesFilter<"CatalogItem"> | string + description?: Prisma.StringNullableWithAggregatesFilter<"CatalogItem"> | string | null + customerDescription?: Prisma.StringNullableWithAggregatesFilter<"CatalogItem"> | string | null + internalNotes?: Prisma.StringNullableWithAggregatesFilter<"CatalogItem"> | string | null + manufacturer?: Prisma.StringNullableWithAggregatesFilter<"CatalogItem"> | string | null + manufactureCwId?: Prisma.IntNullableWithAggregatesFilter<"CatalogItem"> | number | null + partNumber?: Prisma.StringNullableWithAggregatesFilter<"CatalogItem"> | string | null + vendorName?: Prisma.StringNullableWithAggregatesFilter<"CatalogItem"> | string | null + vendorSku?: Prisma.StringNullableWithAggregatesFilter<"CatalogItem"> | string | null + vendorCwId?: Prisma.IntNullableWithAggregatesFilter<"CatalogItem"> | number | null + price?: Prisma.FloatWithAggregatesFilter<"CatalogItem"> | number + cost?: Prisma.FloatWithAggregatesFilter<"CatalogItem"> | number + inactive?: Prisma.BoolWithAggregatesFilter<"CatalogItem"> | boolean + salesTaxable?: Prisma.BoolWithAggregatesFilter<"CatalogItem"> | boolean + onHand?: Prisma.IntWithAggregatesFilter<"CatalogItem"> | number + cwLastUpdated?: Prisma.DateTimeNullableWithAggregatesFilter<"CatalogItem"> | Date | string | null + createdAt?: Prisma.DateTimeWithAggregatesFilter<"CatalogItem"> | Date | string + updatedAt?: Prisma.DateTimeWithAggregatesFilter<"CatalogItem"> | Date | string +} + +export type CatalogItemCreateInput = { + id?: string + cwCatalogId: number + name: string + description?: string | null + customerDescription?: string | null + internalNotes?: string | null + manufacturer?: string | null + manufactureCwId?: number | null + partNumber?: string | null + vendorName?: string | null + vendorSku?: string | null + vendorCwId?: number | null + price: number + cost: number + inactive?: boolean + salesTaxable?: boolean + onHand?: number + cwLastUpdated?: Date | string | null + createdAt?: Date | string + updatedAt?: Date | string + linkedItems?: Prisma.CatalogItemCreateNestedManyWithoutLinkedToInput + linkedTo?: Prisma.CatalogItemCreateNestedManyWithoutLinkedItemsInput +} + +export type CatalogItemUncheckedCreateInput = { + id?: string + cwCatalogId: number + name: string + description?: string | null + customerDescription?: string | null + internalNotes?: string | null + manufacturer?: string | null + manufactureCwId?: number | null + partNumber?: string | null + vendorName?: string | null + vendorSku?: string | null + vendorCwId?: number | null + price: number + cost: number + inactive?: boolean + salesTaxable?: boolean + onHand?: number + cwLastUpdated?: Date | string | null + createdAt?: Date | string + updatedAt?: Date | string + linkedItems?: Prisma.CatalogItemUncheckedCreateNestedManyWithoutLinkedToInput + linkedTo?: Prisma.CatalogItemUncheckedCreateNestedManyWithoutLinkedItemsInput +} + +export type CatalogItemUpdateInput = { + id?: Prisma.StringFieldUpdateOperationsInput | string + cwCatalogId?: Prisma.IntFieldUpdateOperationsInput | number + name?: Prisma.StringFieldUpdateOperationsInput | string + description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + customerDescription?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + internalNotes?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + manufacturer?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + manufactureCwId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + partNumber?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + vendorName?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + vendorSku?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + vendorCwId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + price?: Prisma.FloatFieldUpdateOperationsInput | number + cost?: Prisma.FloatFieldUpdateOperationsInput | number + inactive?: Prisma.BoolFieldUpdateOperationsInput | boolean + salesTaxable?: Prisma.BoolFieldUpdateOperationsInput | boolean + onHand?: Prisma.IntFieldUpdateOperationsInput | number + cwLastUpdated?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + linkedItems?: Prisma.CatalogItemUpdateManyWithoutLinkedToNestedInput + linkedTo?: Prisma.CatalogItemUpdateManyWithoutLinkedItemsNestedInput +} + +export type CatalogItemUncheckedUpdateInput = { + id?: Prisma.StringFieldUpdateOperationsInput | string + cwCatalogId?: Prisma.IntFieldUpdateOperationsInput | number + name?: Prisma.StringFieldUpdateOperationsInput | string + description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + customerDescription?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + internalNotes?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + manufacturer?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + manufactureCwId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + partNumber?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + vendorName?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + vendorSku?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + vendorCwId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + price?: Prisma.FloatFieldUpdateOperationsInput | number + cost?: Prisma.FloatFieldUpdateOperationsInput | number + inactive?: Prisma.BoolFieldUpdateOperationsInput | boolean + salesTaxable?: Prisma.BoolFieldUpdateOperationsInput | boolean + onHand?: Prisma.IntFieldUpdateOperationsInput | number + cwLastUpdated?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + linkedItems?: Prisma.CatalogItemUncheckedUpdateManyWithoutLinkedToNestedInput + linkedTo?: Prisma.CatalogItemUncheckedUpdateManyWithoutLinkedItemsNestedInput +} + +export type CatalogItemCreateManyInput = { + id?: string + cwCatalogId: number + name: string + description?: string | null + customerDescription?: string | null + internalNotes?: string | null + manufacturer?: string | null + manufactureCwId?: number | null + partNumber?: string | null + vendorName?: string | null + vendorSku?: string | null + vendorCwId?: number | null + price: number + cost: number + inactive?: boolean + salesTaxable?: boolean + onHand?: number + cwLastUpdated?: Date | string | null + createdAt?: Date | string + updatedAt?: Date | string +} + +export type CatalogItemUpdateManyMutationInput = { + id?: Prisma.StringFieldUpdateOperationsInput | string + cwCatalogId?: Prisma.IntFieldUpdateOperationsInput | number + name?: Prisma.StringFieldUpdateOperationsInput | string + description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + customerDescription?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + internalNotes?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + manufacturer?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + manufactureCwId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + partNumber?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + vendorName?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + vendorSku?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + vendorCwId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + price?: Prisma.FloatFieldUpdateOperationsInput | number + cost?: Prisma.FloatFieldUpdateOperationsInput | number + inactive?: Prisma.BoolFieldUpdateOperationsInput | boolean + salesTaxable?: Prisma.BoolFieldUpdateOperationsInput | boolean + onHand?: Prisma.IntFieldUpdateOperationsInput | number + cwLastUpdated?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string +} + +export type CatalogItemUncheckedUpdateManyInput = { + id?: Prisma.StringFieldUpdateOperationsInput | string + cwCatalogId?: Prisma.IntFieldUpdateOperationsInput | number + name?: Prisma.StringFieldUpdateOperationsInput | string + description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + customerDescription?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + internalNotes?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + manufacturer?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + manufactureCwId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + partNumber?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + vendorName?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + vendorSku?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + vendorCwId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + price?: Prisma.FloatFieldUpdateOperationsInput | number + cost?: Prisma.FloatFieldUpdateOperationsInput | number + inactive?: Prisma.BoolFieldUpdateOperationsInput | boolean + salesTaxable?: Prisma.BoolFieldUpdateOperationsInput | boolean + onHand?: Prisma.IntFieldUpdateOperationsInput | number + cwLastUpdated?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string +} + +export type CatalogItemListRelationFilter = { + every?: Prisma.CatalogItemWhereInput + some?: Prisma.CatalogItemWhereInput + none?: Prisma.CatalogItemWhereInput +} + +export type CatalogItemOrderByRelationAggregateInput = { + _count?: Prisma.SortOrder +} + +export type CatalogItemCountOrderByAggregateInput = { + id?: Prisma.SortOrder + cwCatalogId?: Prisma.SortOrder + name?: Prisma.SortOrder + description?: Prisma.SortOrder + customerDescription?: Prisma.SortOrder + internalNotes?: Prisma.SortOrder + manufacturer?: Prisma.SortOrder + manufactureCwId?: Prisma.SortOrder + partNumber?: Prisma.SortOrder + vendorName?: Prisma.SortOrder + vendorSku?: Prisma.SortOrder + vendorCwId?: Prisma.SortOrder + price?: Prisma.SortOrder + cost?: Prisma.SortOrder + inactive?: Prisma.SortOrder + salesTaxable?: Prisma.SortOrder + onHand?: Prisma.SortOrder + cwLastUpdated?: Prisma.SortOrder + createdAt?: Prisma.SortOrder + updatedAt?: Prisma.SortOrder +} + +export type CatalogItemAvgOrderByAggregateInput = { + cwCatalogId?: Prisma.SortOrder + manufactureCwId?: Prisma.SortOrder + vendorCwId?: Prisma.SortOrder + price?: Prisma.SortOrder + cost?: Prisma.SortOrder + onHand?: Prisma.SortOrder +} + +export type CatalogItemMaxOrderByAggregateInput = { + id?: Prisma.SortOrder + cwCatalogId?: Prisma.SortOrder + name?: Prisma.SortOrder + description?: Prisma.SortOrder + customerDescription?: Prisma.SortOrder + internalNotes?: Prisma.SortOrder + manufacturer?: Prisma.SortOrder + manufactureCwId?: Prisma.SortOrder + partNumber?: Prisma.SortOrder + vendorName?: Prisma.SortOrder + vendorSku?: Prisma.SortOrder + vendorCwId?: Prisma.SortOrder + price?: Prisma.SortOrder + cost?: Prisma.SortOrder + inactive?: Prisma.SortOrder + salesTaxable?: Prisma.SortOrder + onHand?: Prisma.SortOrder + cwLastUpdated?: Prisma.SortOrder + createdAt?: Prisma.SortOrder + updatedAt?: Prisma.SortOrder +} + +export type CatalogItemMinOrderByAggregateInput = { + id?: Prisma.SortOrder + cwCatalogId?: Prisma.SortOrder + name?: Prisma.SortOrder + description?: Prisma.SortOrder + customerDescription?: Prisma.SortOrder + internalNotes?: Prisma.SortOrder + manufacturer?: Prisma.SortOrder + manufactureCwId?: Prisma.SortOrder + partNumber?: Prisma.SortOrder + vendorName?: Prisma.SortOrder + vendorSku?: Prisma.SortOrder + vendorCwId?: Prisma.SortOrder + price?: Prisma.SortOrder + cost?: Prisma.SortOrder + inactive?: Prisma.SortOrder + salesTaxable?: Prisma.SortOrder + onHand?: Prisma.SortOrder + cwLastUpdated?: Prisma.SortOrder + createdAt?: Prisma.SortOrder + updatedAt?: Prisma.SortOrder +} + +export type CatalogItemSumOrderByAggregateInput = { + cwCatalogId?: Prisma.SortOrder + manufactureCwId?: Prisma.SortOrder + vendorCwId?: Prisma.SortOrder + price?: Prisma.SortOrder + cost?: Prisma.SortOrder + onHand?: Prisma.SortOrder +} + +export type CatalogItemCreateNestedManyWithoutLinkedToInput = { + create?: Prisma.XOR | Prisma.CatalogItemCreateWithoutLinkedToInput[] | Prisma.CatalogItemUncheckedCreateWithoutLinkedToInput[] + connectOrCreate?: Prisma.CatalogItemCreateOrConnectWithoutLinkedToInput | Prisma.CatalogItemCreateOrConnectWithoutLinkedToInput[] + connect?: Prisma.CatalogItemWhereUniqueInput | Prisma.CatalogItemWhereUniqueInput[] +} + +export type CatalogItemCreateNestedManyWithoutLinkedItemsInput = { + create?: Prisma.XOR | Prisma.CatalogItemCreateWithoutLinkedItemsInput[] | Prisma.CatalogItemUncheckedCreateWithoutLinkedItemsInput[] + connectOrCreate?: Prisma.CatalogItemCreateOrConnectWithoutLinkedItemsInput | Prisma.CatalogItemCreateOrConnectWithoutLinkedItemsInput[] + connect?: Prisma.CatalogItemWhereUniqueInput | Prisma.CatalogItemWhereUniqueInput[] +} + +export type CatalogItemUncheckedCreateNestedManyWithoutLinkedToInput = { + create?: Prisma.XOR | Prisma.CatalogItemCreateWithoutLinkedToInput[] | Prisma.CatalogItemUncheckedCreateWithoutLinkedToInput[] + connectOrCreate?: Prisma.CatalogItemCreateOrConnectWithoutLinkedToInput | Prisma.CatalogItemCreateOrConnectWithoutLinkedToInput[] + connect?: Prisma.CatalogItemWhereUniqueInput | Prisma.CatalogItemWhereUniqueInput[] +} + +export type CatalogItemUncheckedCreateNestedManyWithoutLinkedItemsInput = { + create?: Prisma.XOR | Prisma.CatalogItemCreateWithoutLinkedItemsInput[] | Prisma.CatalogItemUncheckedCreateWithoutLinkedItemsInput[] + connectOrCreate?: Prisma.CatalogItemCreateOrConnectWithoutLinkedItemsInput | Prisma.CatalogItemCreateOrConnectWithoutLinkedItemsInput[] + connect?: Prisma.CatalogItemWhereUniqueInput | Prisma.CatalogItemWhereUniqueInput[] +} + +export type NullableIntFieldUpdateOperationsInput = { + set?: number | null + increment?: number + decrement?: number + multiply?: number + divide?: number +} + +export type FloatFieldUpdateOperationsInput = { + set?: number + increment?: number + decrement?: number + multiply?: number + divide?: number +} + +export type CatalogItemUpdateManyWithoutLinkedToNestedInput = { + create?: Prisma.XOR | Prisma.CatalogItemCreateWithoutLinkedToInput[] | Prisma.CatalogItemUncheckedCreateWithoutLinkedToInput[] + connectOrCreate?: Prisma.CatalogItemCreateOrConnectWithoutLinkedToInput | Prisma.CatalogItemCreateOrConnectWithoutLinkedToInput[] + upsert?: Prisma.CatalogItemUpsertWithWhereUniqueWithoutLinkedToInput | Prisma.CatalogItemUpsertWithWhereUniqueWithoutLinkedToInput[] + set?: Prisma.CatalogItemWhereUniqueInput | Prisma.CatalogItemWhereUniqueInput[] + disconnect?: Prisma.CatalogItemWhereUniqueInput | Prisma.CatalogItemWhereUniqueInput[] + delete?: Prisma.CatalogItemWhereUniqueInput | Prisma.CatalogItemWhereUniqueInput[] + connect?: Prisma.CatalogItemWhereUniqueInput | Prisma.CatalogItemWhereUniqueInput[] + update?: Prisma.CatalogItemUpdateWithWhereUniqueWithoutLinkedToInput | Prisma.CatalogItemUpdateWithWhereUniqueWithoutLinkedToInput[] + updateMany?: Prisma.CatalogItemUpdateManyWithWhereWithoutLinkedToInput | Prisma.CatalogItemUpdateManyWithWhereWithoutLinkedToInput[] + deleteMany?: Prisma.CatalogItemScalarWhereInput | Prisma.CatalogItemScalarWhereInput[] +} + +export type CatalogItemUpdateManyWithoutLinkedItemsNestedInput = { + create?: Prisma.XOR | Prisma.CatalogItemCreateWithoutLinkedItemsInput[] | Prisma.CatalogItemUncheckedCreateWithoutLinkedItemsInput[] + connectOrCreate?: Prisma.CatalogItemCreateOrConnectWithoutLinkedItemsInput | Prisma.CatalogItemCreateOrConnectWithoutLinkedItemsInput[] + upsert?: Prisma.CatalogItemUpsertWithWhereUniqueWithoutLinkedItemsInput | Prisma.CatalogItemUpsertWithWhereUniqueWithoutLinkedItemsInput[] + set?: Prisma.CatalogItemWhereUniqueInput | Prisma.CatalogItemWhereUniqueInput[] + disconnect?: Prisma.CatalogItemWhereUniqueInput | Prisma.CatalogItemWhereUniqueInput[] + delete?: Prisma.CatalogItemWhereUniqueInput | Prisma.CatalogItemWhereUniqueInput[] + connect?: Prisma.CatalogItemWhereUniqueInput | Prisma.CatalogItemWhereUniqueInput[] + update?: Prisma.CatalogItemUpdateWithWhereUniqueWithoutLinkedItemsInput | Prisma.CatalogItemUpdateWithWhereUniqueWithoutLinkedItemsInput[] + updateMany?: Prisma.CatalogItemUpdateManyWithWhereWithoutLinkedItemsInput | Prisma.CatalogItemUpdateManyWithWhereWithoutLinkedItemsInput[] + deleteMany?: Prisma.CatalogItemScalarWhereInput | Prisma.CatalogItemScalarWhereInput[] +} + +export type CatalogItemUncheckedUpdateManyWithoutLinkedToNestedInput = { + create?: Prisma.XOR | Prisma.CatalogItemCreateWithoutLinkedToInput[] | Prisma.CatalogItemUncheckedCreateWithoutLinkedToInput[] + connectOrCreate?: Prisma.CatalogItemCreateOrConnectWithoutLinkedToInput | Prisma.CatalogItemCreateOrConnectWithoutLinkedToInput[] + upsert?: Prisma.CatalogItemUpsertWithWhereUniqueWithoutLinkedToInput | Prisma.CatalogItemUpsertWithWhereUniqueWithoutLinkedToInput[] + set?: Prisma.CatalogItemWhereUniqueInput | Prisma.CatalogItemWhereUniqueInput[] + disconnect?: Prisma.CatalogItemWhereUniqueInput | Prisma.CatalogItemWhereUniqueInput[] + delete?: Prisma.CatalogItemWhereUniqueInput | Prisma.CatalogItemWhereUniqueInput[] + connect?: Prisma.CatalogItemWhereUniqueInput | Prisma.CatalogItemWhereUniqueInput[] + update?: Prisma.CatalogItemUpdateWithWhereUniqueWithoutLinkedToInput | Prisma.CatalogItemUpdateWithWhereUniqueWithoutLinkedToInput[] + updateMany?: Prisma.CatalogItemUpdateManyWithWhereWithoutLinkedToInput | Prisma.CatalogItemUpdateManyWithWhereWithoutLinkedToInput[] + deleteMany?: Prisma.CatalogItemScalarWhereInput | Prisma.CatalogItemScalarWhereInput[] +} + +export type CatalogItemUncheckedUpdateManyWithoutLinkedItemsNestedInput = { + create?: Prisma.XOR | Prisma.CatalogItemCreateWithoutLinkedItemsInput[] | Prisma.CatalogItemUncheckedCreateWithoutLinkedItemsInput[] + connectOrCreate?: Prisma.CatalogItemCreateOrConnectWithoutLinkedItemsInput | Prisma.CatalogItemCreateOrConnectWithoutLinkedItemsInput[] + upsert?: Prisma.CatalogItemUpsertWithWhereUniqueWithoutLinkedItemsInput | Prisma.CatalogItemUpsertWithWhereUniqueWithoutLinkedItemsInput[] + set?: Prisma.CatalogItemWhereUniqueInput | Prisma.CatalogItemWhereUniqueInput[] + disconnect?: Prisma.CatalogItemWhereUniqueInput | Prisma.CatalogItemWhereUniqueInput[] + delete?: Prisma.CatalogItemWhereUniqueInput | Prisma.CatalogItemWhereUniqueInput[] + connect?: Prisma.CatalogItemWhereUniqueInput | Prisma.CatalogItemWhereUniqueInput[] + update?: Prisma.CatalogItemUpdateWithWhereUniqueWithoutLinkedItemsInput | Prisma.CatalogItemUpdateWithWhereUniqueWithoutLinkedItemsInput[] + updateMany?: Prisma.CatalogItemUpdateManyWithWhereWithoutLinkedItemsInput | Prisma.CatalogItemUpdateManyWithWhereWithoutLinkedItemsInput[] + deleteMany?: Prisma.CatalogItemScalarWhereInput | Prisma.CatalogItemScalarWhereInput[] +} + +export type CatalogItemCreateWithoutLinkedToInput = { + id?: string + cwCatalogId: number + name: string + description?: string | null + customerDescription?: string | null + internalNotes?: string | null + manufacturer?: string | null + manufactureCwId?: number | null + partNumber?: string | null + vendorName?: string | null + vendorSku?: string | null + vendorCwId?: number | null + price: number + cost: number + inactive?: boolean + salesTaxable?: boolean + onHand?: number + cwLastUpdated?: Date | string | null + createdAt?: Date | string + updatedAt?: Date | string + linkedItems?: Prisma.CatalogItemCreateNestedManyWithoutLinkedToInput +} + +export type CatalogItemUncheckedCreateWithoutLinkedToInput = { + id?: string + cwCatalogId: number + name: string + description?: string | null + customerDescription?: string | null + internalNotes?: string | null + manufacturer?: string | null + manufactureCwId?: number | null + partNumber?: string | null + vendorName?: string | null + vendorSku?: string | null + vendorCwId?: number | null + price: number + cost: number + inactive?: boolean + salesTaxable?: boolean + onHand?: number + cwLastUpdated?: Date | string | null + createdAt?: Date | string + updatedAt?: Date | string + linkedItems?: Prisma.CatalogItemUncheckedCreateNestedManyWithoutLinkedToInput +} + +export type CatalogItemCreateOrConnectWithoutLinkedToInput = { + where: Prisma.CatalogItemWhereUniqueInput + create: Prisma.XOR +} + +export type CatalogItemCreateWithoutLinkedItemsInput = { + id?: string + cwCatalogId: number + name: string + description?: string | null + customerDescription?: string | null + internalNotes?: string | null + manufacturer?: string | null + manufactureCwId?: number | null + partNumber?: string | null + vendorName?: string | null + vendorSku?: string | null + vendorCwId?: number | null + price: number + cost: number + inactive?: boolean + salesTaxable?: boolean + onHand?: number + cwLastUpdated?: Date | string | null + createdAt?: Date | string + updatedAt?: Date | string + linkedTo?: Prisma.CatalogItemCreateNestedManyWithoutLinkedItemsInput +} + +export type CatalogItemUncheckedCreateWithoutLinkedItemsInput = { + id?: string + cwCatalogId: number + name: string + description?: string | null + customerDescription?: string | null + internalNotes?: string | null + manufacturer?: string | null + manufactureCwId?: number | null + partNumber?: string | null + vendorName?: string | null + vendorSku?: string | null + vendorCwId?: number | null + price: number + cost: number + inactive?: boolean + salesTaxable?: boolean + onHand?: number + cwLastUpdated?: Date | string | null + createdAt?: Date | string + updatedAt?: Date | string + linkedTo?: Prisma.CatalogItemUncheckedCreateNestedManyWithoutLinkedItemsInput +} + +export type CatalogItemCreateOrConnectWithoutLinkedItemsInput = { + where: Prisma.CatalogItemWhereUniqueInput + create: Prisma.XOR +} + +export type CatalogItemUpsertWithWhereUniqueWithoutLinkedToInput = { + where: Prisma.CatalogItemWhereUniqueInput + update: Prisma.XOR + create: Prisma.XOR +} + +export type CatalogItemUpdateWithWhereUniqueWithoutLinkedToInput = { + where: Prisma.CatalogItemWhereUniqueInput + data: Prisma.XOR +} + +export type CatalogItemUpdateManyWithWhereWithoutLinkedToInput = { + where: Prisma.CatalogItemScalarWhereInput + data: Prisma.XOR +} + +export type CatalogItemScalarWhereInput = { + AND?: Prisma.CatalogItemScalarWhereInput | Prisma.CatalogItemScalarWhereInput[] + OR?: Prisma.CatalogItemScalarWhereInput[] + NOT?: Prisma.CatalogItemScalarWhereInput | Prisma.CatalogItemScalarWhereInput[] + id?: Prisma.StringFilter<"CatalogItem"> | string + cwCatalogId?: Prisma.IntFilter<"CatalogItem"> | number + name?: Prisma.StringFilter<"CatalogItem"> | string + description?: Prisma.StringNullableFilter<"CatalogItem"> | string | null + customerDescription?: Prisma.StringNullableFilter<"CatalogItem"> | string | null + internalNotes?: Prisma.StringNullableFilter<"CatalogItem"> | string | null + manufacturer?: Prisma.StringNullableFilter<"CatalogItem"> | string | null + manufactureCwId?: Prisma.IntNullableFilter<"CatalogItem"> | number | null + partNumber?: Prisma.StringNullableFilter<"CatalogItem"> | string | null + vendorName?: Prisma.StringNullableFilter<"CatalogItem"> | string | null + vendorSku?: Prisma.StringNullableFilter<"CatalogItem"> | string | null + vendorCwId?: Prisma.IntNullableFilter<"CatalogItem"> | number | null + price?: Prisma.FloatFilter<"CatalogItem"> | number + cost?: Prisma.FloatFilter<"CatalogItem"> | number + inactive?: Prisma.BoolFilter<"CatalogItem"> | boolean + salesTaxable?: Prisma.BoolFilter<"CatalogItem"> | boolean + onHand?: Prisma.IntFilter<"CatalogItem"> | number + cwLastUpdated?: Prisma.DateTimeNullableFilter<"CatalogItem"> | Date | string | null + createdAt?: Prisma.DateTimeFilter<"CatalogItem"> | Date | string + updatedAt?: Prisma.DateTimeFilter<"CatalogItem"> | Date | string +} + +export type CatalogItemUpsertWithWhereUniqueWithoutLinkedItemsInput = { + where: Prisma.CatalogItemWhereUniqueInput + update: Prisma.XOR + create: Prisma.XOR +} + +export type CatalogItemUpdateWithWhereUniqueWithoutLinkedItemsInput = { + where: Prisma.CatalogItemWhereUniqueInput + data: Prisma.XOR +} + +export type CatalogItemUpdateManyWithWhereWithoutLinkedItemsInput = { + where: Prisma.CatalogItemScalarWhereInput + data: Prisma.XOR +} + +export type CatalogItemUpdateWithoutLinkedToInput = { + id?: Prisma.StringFieldUpdateOperationsInput | string + cwCatalogId?: Prisma.IntFieldUpdateOperationsInput | number + name?: Prisma.StringFieldUpdateOperationsInput | string + description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + customerDescription?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + internalNotes?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + manufacturer?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + manufactureCwId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + partNumber?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + vendorName?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + vendorSku?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + vendorCwId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + price?: Prisma.FloatFieldUpdateOperationsInput | number + cost?: Prisma.FloatFieldUpdateOperationsInput | number + inactive?: Prisma.BoolFieldUpdateOperationsInput | boolean + salesTaxable?: Prisma.BoolFieldUpdateOperationsInput | boolean + onHand?: Prisma.IntFieldUpdateOperationsInput | number + cwLastUpdated?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + linkedItems?: Prisma.CatalogItemUpdateManyWithoutLinkedToNestedInput +} + +export type CatalogItemUncheckedUpdateWithoutLinkedToInput = { + id?: Prisma.StringFieldUpdateOperationsInput | string + cwCatalogId?: Prisma.IntFieldUpdateOperationsInput | number + name?: Prisma.StringFieldUpdateOperationsInput | string + description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + customerDescription?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + internalNotes?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + manufacturer?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + manufactureCwId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + partNumber?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + vendorName?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + vendorSku?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + vendorCwId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + price?: Prisma.FloatFieldUpdateOperationsInput | number + cost?: Prisma.FloatFieldUpdateOperationsInput | number + inactive?: Prisma.BoolFieldUpdateOperationsInput | boolean + salesTaxable?: Prisma.BoolFieldUpdateOperationsInput | boolean + onHand?: Prisma.IntFieldUpdateOperationsInput | number + cwLastUpdated?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + linkedItems?: Prisma.CatalogItemUncheckedUpdateManyWithoutLinkedToNestedInput +} + +export type CatalogItemUncheckedUpdateManyWithoutLinkedToInput = { + id?: Prisma.StringFieldUpdateOperationsInput | string + cwCatalogId?: Prisma.IntFieldUpdateOperationsInput | number + name?: Prisma.StringFieldUpdateOperationsInput | string + description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + customerDescription?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + internalNotes?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + manufacturer?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + manufactureCwId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + partNumber?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + vendorName?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + vendorSku?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + vendorCwId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + price?: Prisma.FloatFieldUpdateOperationsInput | number + cost?: Prisma.FloatFieldUpdateOperationsInput | number + inactive?: Prisma.BoolFieldUpdateOperationsInput | boolean + salesTaxable?: Prisma.BoolFieldUpdateOperationsInput | boolean + onHand?: Prisma.IntFieldUpdateOperationsInput | number + cwLastUpdated?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string +} + +export type CatalogItemUpdateWithoutLinkedItemsInput = { + id?: Prisma.StringFieldUpdateOperationsInput | string + cwCatalogId?: Prisma.IntFieldUpdateOperationsInput | number + name?: Prisma.StringFieldUpdateOperationsInput | string + description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + customerDescription?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + internalNotes?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + manufacturer?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + manufactureCwId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + partNumber?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + vendorName?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + vendorSku?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + vendorCwId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + price?: Prisma.FloatFieldUpdateOperationsInput | number + cost?: Prisma.FloatFieldUpdateOperationsInput | number + inactive?: Prisma.BoolFieldUpdateOperationsInput | boolean + salesTaxable?: Prisma.BoolFieldUpdateOperationsInput | boolean + onHand?: Prisma.IntFieldUpdateOperationsInput | number + cwLastUpdated?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + linkedTo?: Prisma.CatalogItemUpdateManyWithoutLinkedItemsNestedInput +} + +export type CatalogItemUncheckedUpdateWithoutLinkedItemsInput = { + id?: Prisma.StringFieldUpdateOperationsInput | string + cwCatalogId?: Prisma.IntFieldUpdateOperationsInput | number + name?: Prisma.StringFieldUpdateOperationsInput | string + description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + customerDescription?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + internalNotes?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + manufacturer?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + manufactureCwId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + partNumber?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + vendorName?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + vendorSku?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + vendorCwId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + price?: Prisma.FloatFieldUpdateOperationsInput | number + cost?: Prisma.FloatFieldUpdateOperationsInput | number + inactive?: Prisma.BoolFieldUpdateOperationsInput | boolean + salesTaxable?: Prisma.BoolFieldUpdateOperationsInput | boolean + onHand?: Prisma.IntFieldUpdateOperationsInput | number + cwLastUpdated?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + linkedTo?: Prisma.CatalogItemUncheckedUpdateManyWithoutLinkedItemsNestedInput +} + +export type CatalogItemUncheckedUpdateManyWithoutLinkedItemsInput = { + id?: Prisma.StringFieldUpdateOperationsInput | string + cwCatalogId?: Prisma.IntFieldUpdateOperationsInput | number + name?: Prisma.StringFieldUpdateOperationsInput | string + description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + customerDescription?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + internalNotes?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + manufacturer?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + manufactureCwId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + partNumber?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + vendorName?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + vendorSku?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + vendorCwId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + price?: Prisma.FloatFieldUpdateOperationsInput | number + cost?: Prisma.FloatFieldUpdateOperationsInput | number + inactive?: Prisma.BoolFieldUpdateOperationsInput | boolean + salesTaxable?: Prisma.BoolFieldUpdateOperationsInput | boolean + onHand?: Prisma.IntFieldUpdateOperationsInput | number + cwLastUpdated?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string +} + + +/** + * Count Type CatalogItemCountOutputType + */ + +export type CatalogItemCountOutputType = { + linkedItems: number + linkedTo: number +} + +export type CatalogItemCountOutputTypeSelect = { + linkedItems?: boolean | CatalogItemCountOutputTypeCountLinkedItemsArgs + linkedTo?: boolean | CatalogItemCountOutputTypeCountLinkedToArgs +} + +/** + * CatalogItemCountOutputType without action + */ +export type CatalogItemCountOutputTypeDefaultArgs = { + /** + * Select specific fields to fetch from the CatalogItemCountOutputType + */ + select?: Prisma.CatalogItemCountOutputTypeSelect | null +} + +/** + * CatalogItemCountOutputType without action + */ +export type CatalogItemCountOutputTypeCountLinkedItemsArgs = { + where?: Prisma.CatalogItemWhereInput +} + +/** + * CatalogItemCountOutputType without action + */ +export type CatalogItemCountOutputTypeCountLinkedToArgs = { + where?: Prisma.CatalogItemWhereInput +} + + +export type CatalogItemSelect = runtime.Types.Extensions.GetSelect<{ + id?: boolean + cwCatalogId?: boolean + name?: boolean + description?: boolean + customerDescription?: boolean + internalNotes?: boolean + manufacturer?: boolean + manufactureCwId?: boolean + partNumber?: boolean + vendorName?: boolean + vendorSku?: boolean + vendorCwId?: boolean + price?: boolean + cost?: boolean + inactive?: boolean + salesTaxable?: boolean + onHand?: boolean + cwLastUpdated?: boolean + createdAt?: boolean + updatedAt?: boolean + linkedItems?: boolean | Prisma.CatalogItem$linkedItemsArgs + linkedTo?: boolean | Prisma.CatalogItem$linkedToArgs + _count?: boolean | Prisma.CatalogItemCountOutputTypeDefaultArgs +}, ExtArgs["result"]["catalogItem"]> + +export type CatalogItemSelectCreateManyAndReturn = runtime.Types.Extensions.GetSelect<{ + id?: boolean + cwCatalogId?: boolean + name?: boolean + description?: boolean + customerDescription?: boolean + internalNotes?: boolean + manufacturer?: boolean + manufactureCwId?: boolean + partNumber?: boolean + vendorName?: boolean + vendorSku?: boolean + vendorCwId?: boolean + price?: boolean + cost?: boolean + inactive?: boolean + salesTaxable?: boolean + onHand?: boolean + cwLastUpdated?: boolean + createdAt?: boolean + updatedAt?: boolean +}, ExtArgs["result"]["catalogItem"]> + +export type CatalogItemSelectUpdateManyAndReturn = runtime.Types.Extensions.GetSelect<{ + id?: boolean + cwCatalogId?: boolean + name?: boolean + description?: boolean + customerDescription?: boolean + internalNotes?: boolean + manufacturer?: boolean + manufactureCwId?: boolean + partNumber?: boolean + vendorName?: boolean + vendorSku?: boolean + vendorCwId?: boolean + price?: boolean + cost?: boolean + inactive?: boolean + salesTaxable?: boolean + onHand?: boolean + cwLastUpdated?: boolean + createdAt?: boolean + updatedAt?: boolean +}, ExtArgs["result"]["catalogItem"]> + +export type CatalogItemSelectScalar = { + id?: boolean + cwCatalogId?: boolean + name?: boolean + description?: boolean + customerDescription?: boolean + internalNotes?: boolean + manufacturer?: boolean + manufactureCwId?: boolean + partNumber?: boolean + vendorName?: boolean + vendorSku?: boolean + vendorCwId?: boolean + price?: boolean + cost?: boolean + inactive?: boolean + salesTaxable?: boolean + onHand?: boolean + cwLastUpdated?: boolean + createdAt?: boolean + updatedAt?: boolean +} + +export type CatalogItemOmit = runtime.Types.Extensions.GetOmit<"id" | "cwCatalogId" | "name" | "description" | "customerDescription" | "internalNotes" | "manufacturer" | "manufactureCwId" | "partNumber" | "vendorName" | "vendorSku" | "vendorCwId" | "price" | "cost" | "inactive" | "salesTaxable" | "onHand" | "cwLastUpdated" | "createdAt" | "updatedAt", ExtArgs["result"]["catalogItem"]> +export type CatalogItemInclude = { + linkedItems?: boolean | Prisma.CatalogItem$linkedItemsArgs + linkedTo?: boolean | Prisma.CatalogItem$linkedToArgs + _count?: boolean | Prisma.CatalogItemCountOutputTypeDefaultArgs +} +export type CatalogItemIncludeCreateManyAndReturn = {} +export type CatalogItemIncludeUpdateManyAndReturn = {} + +export type $CatalogItemPayload = { + name: "CatalogItem" + objects: { + linkedItems: Prisma.$CatalogItemPayload[] + linkedTo: Prisma.$CatalogItemPayload[] + } + scalars: runtime.Types.Extensions.GetPayloadResult<{ + id: string + cwCatalogId: number + name: string + description: string | null + customerDescription: string | null + internalNotes: string | null + manufacturer: string | null + manufactureCwId: number | null + partNumber: string | null + vendorName: string | null + vendorSku: string | null + vendorCwId: number | null + price: number + cost: number + inactive: boolean + salesTaxable: boolean + onHand: number + cwLastUpdated: Date | null + createdAt: Date + updatedAt: Date + }, ExtArgs["result"]["catalogItem"]> + composites: {} +} + +export type CatalogItemGetPayload = runtime.Types.Result.GetResult + +export type CatalogItemCountArgs = + Omit & { + select?: CatalogItemCountAggregateInputType | true + } + +export interface CatalogItemDelegate { + [K: symbol]: { types: Prisma.TypeMap['model']['CatalogItem'], meta: { name: 'CatalogItem' } } + /** + * Find zero or one CatalogItem that matches the filter. + * @param {CatalogItemFindUniqueArgs} args - Arguments to find a CatalogItem + * @example + * // Get one CatalogItem + * const catalogItem = await prisma.catalogItem.findUnique({ + * where: { + * // ... provide filter here + * } + * }) + */ + findUnique(args: Prisma.SelectSubset>): Prisma.Prisma__CatalogItemClient, T, "findUnique", GlobalOmitOptions> | null, null, ExtArgs, GlobalOmitOptions> + + /** + * Find one CatalogItem that matches the filter or throw an error with `error.code='P2025'` + * if no matches were found. + * @param {CatalogItemFindUniqueOrThrowArgs} args - Arguments to find a CatalogItem + * @example + * // Get one CatalogItem + * const catalogItem = await prisma.catalogItem.findUniqueOrThrow({ + * where: { + * // ... provide filter here + * } + * }) + */ + findUniqueOrThrow(args: Prisma.SelectSubset>): Prisma.Prisma__CatalogItemClient, T, "findUniqueOrThrow", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> + + /** + * Find the first CatalogItem that matches the filter. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {CatalogItemFindFirstArgs} args - Arguments to find a CatalogItem + * @example + * // Get one CatalogItem + * const catalogItem = await prisma.catalogItem.findFirst({ + * where: { + * // ... provide filter here + * } + * }) + */ + findFirst(args?: Prisma.SelectSubset>): Prisma.Prisma__CatalogItemClient, T, "findFirst", GlobalOmitOptions> | null, null, ExtArgs, GlobalOmitOptions> + + /** + * Find the first CatalogItem that matches the filter or + * throw `PrismaKnownClientError` with `P2025` code if no matches were found. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {CatalogItemFindFirstOrThrowArgs} args - Arguments to find a CatalogItem + * @example + * // Get one CatalogItem + * const catalogItem = await prisma.catalogItem.findFirstOrThrow({ + * where: { + * // ... provide filter here + * } + * }) + */ + findFirstOrThrow(args?: Prisma.SelectSubset>): Prisma.Prisma__CatalogItemClient, T, "findFirstOrThrow", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> + + /** + * Find zero or more CatalogItems that matches the filter. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {CatalogItemFindManyArgs} args - Arguments to filter and select certain fields only. + * @example + * // Get all CatalogItems + * const catalogItems = await prisma.catalogItem.findMany() + * + * // Get first 10 CatalogItems + * const catalogItems = await prisma.catalogItem.findMany({ take: 10 }) + * + * // Only select the `id` + * const catalogItemWithIdOnly = await prisma.catalogItem.findMany({ select: { id: true } }) + * + */ + findMany(args?: Prisma.SelectSubset>): Prisma.PrismaPromise, T, "findMany", GlobalOmitOptions>> + + /** + * Create a CatalogItem. + * @param {CatalogItemCreateArgs} args - Arguments to create a CatalogItem. + * @example + * // Create one CatalogItem + * const CatalogItem = await prisma.catalogItem.create({ + * data: { + * // ... data to create a CatalogItem + * } + * }) + * + */ + create(args: Prisma.SelectSubset>): Prisma.Prisma__CatalogItemClient, T, "create", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> + + /** + * Create many CatalogItems. + * @param {CatalogItemCreateManyArgs} args - Arguments to create many CatalogItems. + * @example + * // Create many CatalogItems + * const catalogItem = await prisma.catalogItem.createMany({ + * data: [ + * // ... provide data here + * ] + * }) + * + */ + createMany(args?: Prisma.SelectSubset>): Prisma.PrismaPromise + + /** + * Create many CatalogItems and returns the data saved in the database. + * @param {CatalogItemCreateManyAndReturnArgs} args - Arguments to create many CatalogItems. + * @example + * // Create many CatalogItems + * const catalogItem = await prisma.catalogItem.createManyAndReturn({ + * data: [ + * // ... provide data here + * ] + * }) + * + * // Create many CatalogItems and only return the `id` + * const catalogItemWithIdOnly = await prisma.catalogItem.createManyAndReturn({ + * select: { id: true }, + * data: [ + * // ... provide data here + * ] + * }) + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * + */ + createManyAndReturn(args?: Prisma.SelectSubset>): Prisma.PrismaPromise, T, "createManyAndReturn", GlobalOmitOptions>> + + /** + * Delete a CatalogItem. + * @param {CatalogItemDeleteArgs} args - Arguments to delete one CatalogItem. + * @example + * // Delete one CatalogItem + * const CatalogItem = await prisma.catalogItem.delete({ + * where: { + * // ... filter to delete one CatalogItem + * } + * }) + * + */ + delete(args: Prisma.SelectSubset>): Prisma.Prisma__CatalogItemClient, T, "delete", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> + + /** + * Update one CatalogItem. + * @param {CatalogItemUpdateArgs} args - Arguments to update one CatalogItem. + * @example + * // Update one CatalogItem + * const catalogItem = await prisma.catalogItem.update({ + * where: { + * // ... provide filter here + * }, + * data: { + * // ... provide data here + * } + * }) + * + */ + update(args: Prisma.SelectSubset>): Prisma.Prisma__CatalogItemClient, T, "update", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> + + /** + * Delete zero or more CatalogItems. + * @param {CatalogItemDeleteManyArgs} args - Arguments to filter CatalogItems to delete. + * @example + * // Delete a few CatalogItems + * const { count } = await prisma.catalogItem.deleteMany({ + * where: { + * // ... provide filter here + * } + * }) + * + */ + deleteMany(args?: Prisma.SelectSubset>): Prisma.PrismaPromise + + /** + * Update zero or more CatalogItems. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {CatalogItemUpdateManyArgs} args - Arguments to update one or more rows. + * @example + * // Update many CatalogItems + * const catalogItem = await prisma.catalogItem.updateMany({ + * where: { + * // ... provide filter here + * }, + * data: { + * // ... provide data here + * } + * }) + * + */ + updateMany(args: Prisma.SelectSubset>): Prisma.PrismaPromise + + /** + * Update zero or more CatalogItems and returns the data updated in the database. + * @param {CatalogItemUpdateManyAndReturnArgs} args - Arguments to update many CatalogItems. + * @example + * // Update many CatalogItems + * const catalogItem = await prisma.catalogItem.updateManyAndReturn({ + * where: { + * // ... provide filter here + * }, + * data: [ + * // ... provide data here + * ] + * }) + * + * // Update zero or more CatalogItems and only return the `id` + * const catalogItemWithIdOnly = await prisma.catalogItem.updateManyAndReturn({ + * select: { id: true }, + * where: { + * // ... provide filter here + * }, + * data: [ + * // ... provide data here + * ] + * }) + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * + */ + updateManyAndReturn(args: Prisma.SelectSubset>): Prisma.PrismaPromise, T, "updateManyAndReturn", GlobalOmitOptions>> + + /** + * Create or update one CatalogItem. + * @param {CatalogItemUpsertArgs} args - Arguments to update or create a CatalogItem. + * @example + * // Update or create a CatalogItem + * const catalogItem = await prisma.catalogItem.upsert({ + * create: { + * // ... data to create a CatalogItem + * }, + * update: { + * // ... in case it already exists, update + * }, + * where: { + * // ... the filter for the CatalogItem we want to update + * } + * }) + */ + upsert(args: Prisma.SelectSubset>): Prisma.Prisma__CatalogItemClient, T, "upsert", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> + + + /** + * Count the number of CatalogItems. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {CatalogItemCountArgs} args - Arguments to filter CatalogItems to count. + * @example + * // Count the number of CatalogItems + * const count = await prisma.catalogItem.count({ + * where: { + * // ... the filter for the CatalogItems we want to count + * } + * }) + **/ + count( + args?: Prisma.Subset, + ): Prisma.PrismaPromise< + T extends runtime.Types.Utils.Record<'select', any> + ? T['select'] extends true + ? number + : Prisma.GetScalarType + : number + > + + /** + * Allows you to perform aggregations operations on a CatalogItem. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {CatalogItemAggregateArgs} args - Select which aggregations you would like to apply and on what fields. + * @example + * // Ordered by age ascending + * // Where email contains prisma.io + * // Limited to the 10 users + * const aggregations = await prisma.user.aggregate({ + * _avg: { + * age: true, + * }, + * where: { + * email: { + * contains: "prisma.io", + * }, + * }, + * orderBy: { + * age: "asc", + * }, + * take: 10, + * }) + **/ + aggregate(args: Prisma.Subset): Prisma.PrismaPromise> + + /** + * Group by CatalogItem. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {CatalogItemGroupByArgs} args - Group by arguments. + * @example + * // Group by city, order by createdAt, get count + * const result = await prisma.user.groupBy({ + * by: ['city', 'createdAt'], + * orderBy: { + * createdAt: true + * }, + * _count: { + * _all: true + * }, + * }) + * + **/ + groupBy< + T extends CatalogItemGroupByArgs, + HasSelectOrTake extends Prisma.Or< + Prisma.Extends<'skip', Prisma.Keys>, + Prisma.Extends<'take', Prisma.Keys> + >, + OrderByArg extends Prisma.True extends HasSelectOrTake + ? { orderBy: CatalogItemGroupByArgs['orderBy'] } + : { orderBy?: CatalogItemGroupByArgs['orderBy'] }, + OrderFields extends Prisma.ExcludeUnderscoreKeys>>, + ByFields extends Prisma.MaybeTupleToUnion, + ByValid extends Prisma.Has, + HavingFields extends Prisma.GetHavingFields, + HavingValid extends Prisma.Has, + ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, + InputErrors extends ByEmpty extends Prisma.True + ? `Error: "by" must not be empty.` + : HavingValid extends Prisma.False + ? { + [P in HavingFields]: P extends ByFields + ? never + : P extends string + ? `Error: Field "${P}" used in "having" needs to be provided in "by".` + : [ + Error, + 'Field ', + P, + ` in "having" needs to be provided in "by"`, + ] + }[HavingFields] + : 'take' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "take", you also need to provide "orderBy"' + : 'skip' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "skip", you also need to provide "orderBy"' + : ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + >(args: Prisma.SubsetIntersection & InputErrors): {} extends InputErrors ? GetCatalogItemGroupByPayload : Prisma.PrismaPromise +/** + * Fields of the CatalogItem model + */ +readonly fields: CatalogItemFieldRefs; +} + +/** + * The delegate class that acts as a "Promise-like" for CatalogItem. + * Why is this prefixed with `Prisma__`? + * Because we want to prevent naming conflicts as mentioned in + * https://github.com/prisma/prisma-client-js/issues/707 + */ +export interface Prisma__CatalogItemClient extends Prisma.PrismaPromise { + readonly [Symbol.toStringTag]: "PrismaPromise" + linkedItems = {}>(args?: Prisma.Subset>): Prisma.PrismaPromise, T, "findMany", GlobalOmitOptions> | Null> + linkedTo = {}>(args?: Prisma.Subset>): Prisma.PrismaPromise, T, "findMany", GlobalOmitOptions> | Null> + /** + * Attaches callbacks for the resolution and/or rejection of the Promise. + * @param onfulfilled The callback to execute when the Promise is resolved. + * @param onrejected The callback to execute when the Promise is rejected. + * @returns A Promise for the completion of which ever callback is executed. + */ + then(onfulfilled?: ((value: T) => TResult1 | PromiseLike) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike) | undefined | null): runtime.Types.Utils.JsPromise + /** + * Attaches a callback for only the rejection of the Promise. + * @param onrejected The callback to execute when the Promise is rejected. + * @returns A Promise for the completion of the callback. + */ + catch(onrejected?: ((reason: any) => TResult | PromiseLike) | undefined | null): runtime.Types.Utils.JsPromise + /** + * Attaches a callback that is invoked when the Promise is settled (fulfilled or rejected). The + * resolved value cannot be modified from the callback. + * @param onfinally The callback to execute when the Promise is settled (fulfilled or rejected). + * @returns A Promise for the completion of the callback. + */ + finally(onfinally?: (() => void) | undefined | null): runtime.Types.Utils.JsPromise +} + + + + +/** + * Fields of the CatalogItem model + */ +export interface CatalogItemFieldRefs { + readonly id: Prisma.FieldRef<"CatalogItem", 'String'> + readonly cwCatalogId: Prisma.FieldRef<"CatalogItem", 'Int'> + readonly name: Prisma.FieldRef<"CatalogItem", 'String'> + readonly description: Prisma.FieldRef<"CatalogItem", 'String'> + readonly customerDescription: Prisma.FieldRef<"CatalogItem", 'String'> + readonly internalNotes: Prisma.FieldRef<"CatalogItem", 'String'> + readonly manufacturer: Prisma.FieldRef<"CatalogItem", 'String'> + readonly manufactureCwId: Prisma.FieldRef<"CatalogItem", 'Int'> + readonly partNumber: Prisma.FieldRef<"CatalogItem", 'String'> + readonly vendorName: Prisma.FieldRef<"CatalogItem", 'String'> + readonly vendorSku: Prisma.FieldRef<"CatalogItem", 'String'> + readonly vendorCwId: Prisma.FieldRef<"CatalogItem", 'Int'> + readonly price: Prisma.FieldRef<"CatalogItem", 'Float'> + readonly cost: Prisma.FieldRef<"CatalogItem", 'Float'> + readonly inactive: Prisma.FieldRef<"CatalogItem", 'Boolean'> + readonly salesTaxable: Prisma.FieldRef<"CatalogItem", 'Boolean'> + readonly onHand: Prisma.FieldRef<"CatalogItem", 'Int'> + readonly cwLastUpdated: Prisma.FieldRef<"CatalogItem", 'DateTime'> + readonly createdAt: Prisma.FieldRef<"CatalogItem", 'DateTime'> + readonly updatedAt: Prisma.FieldRef<"CatalogItem", 'DateTime'> +} + + +// Custom InputTypes +/** + * CatalogItem findUnique + */ +export type CatalogItemFindUniqueArgs = { + /** + * Select specific fields to fetch from the CatalogItem + */ + select?: Prisma.CatalogItemSelect | null + /** + * Omit specific fields from the CatalogItem + */ + omit?: Prisma.CatalogItemOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: Prisma.CatalogItemInclude | null + /** + * Filter, which CatalogItem to fetch. + */ + where: Prisma.CatalogItemWhereUniqueInput +} + +/** + * CatalogItem findUniqueOrThrow + */ +export type CatalogItemFindUniqueOrThrowArgs = { + /** + * Select specific fields to fetch from the CatalogItem + */ + select?: Prisma.CatalogItemSelect | null + /** + * Omit specific fields from the CatalogItem + */ + omit?: Prisma.CatalogItemOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: Prisma.CatalogItemInclude | null + /** + * Filter, which CatalogItem to fetch. + */ + where: Prisma.CatalogItemWhereUniqueInput +} + +/** + * CatalogItem findFirst + */ +export type CatalogItemFindFirstArgs = { + /** + * Select specific fields to fetch from the CatalogItem + */ + select?: Prisma.CatalogItemSelect | null + /** + * Omit specific fields from the CatalogItem + */ + omit?: Prisma.CatalogItemOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: Prisma.CatalogItemInclude | null + /** + * Filter, which CatalogItem to fetch. + */ + where?: Prisma.CatalogItemWhereInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/sorting Sorting Docs} + * + * Determine the order of CatalogItems to fetch. + */ + orderBy?: Prisma.CatalogItemOrderByWithRelationInput | Prisma.CatalogItemOrderByWithRelationInput[] + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination#cursor-based-pagination Cursor Docs} + * + * Sets the position for searching for CatalogItems. + */ + cursor?: Prisma.CatalogItemWhereUniqueInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Take `±n` CatalogItems from the position of the cursor. + */ + take?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Skip the first `n` CatalogItems. + */ + skip?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/distinct Distinct Docs} + * + * Filter by unique combinations of CatalogItems. + */ + distinct?: Prisma.CatalogItemScalarFieldEnum | Prisma.CatalogItemScalarFieldEnum[] +} + +/** + * CatalogItem findFirstOrThrow + */ +export type CatalogItemFindFirstOrThrowArgs = { + /** + * Select specific fields to fetch from the CatalogItem + */ + select?: Prisma.CatalogItemSelect | null + /** + * Omit specific fields from the CatalogItem + */ + omit?: Prisma.CatalogItemOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: Prisma.CatalogItemInclude | null + /** + * Filter, which CatalogItem to fetch. + */ + where?: Prisma.CatalogItemWhereInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/sorting Sorting Docs} + * + * Determine the order of CatalogItems to fetch. + */ + orderBy?: Prisma.CatalogItemOrderByWithRelationInput | Prisma.CatalogItemOrderByWithRelationInput[] + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination#cursor-based-pagination Cursor Docs} + * + * Sets the position for searching for CatalogItems. + */ + cursor?: Prisma.CatalogItemWhereUniqueInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Take `±n` CatalogItems from the position of the cursor. + */ + take?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Skip the first `n` CatalogItems. + */ + skip?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/distinct Distinct Docs} + * + * Filter by unique combinations of CatalogItems. + */ + distinct?: Prisma.CatalogItemScalarFieldEnum | Prisma.CatalogItemScalarFieldEnum[] +} + +/** + * CatalogItem findMany + */ +export type CatalogItemFindManyArgs = { + /** + * Select specific fields to fetch from the CatalogItem + */ + select?: Prisma.CatalogItemSelect | null + /** + * Omit specific fields from the CatalogItem + */ + omit?: Prisma.CatalogItemOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: Prisma.CatalogItemInclude | null + /** + * Filter, which CatalogItems to fetch. + */ + where?: Prisma.CatalogItemWhereInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/sorting Sorting Docs} + * + * Determine the order of CatalogItems to fetch. + */ + orderBy?: Prisma.CatalogItemOrderByWithRelationInput | Prisma.CatalogItemOrderByWithRelationInput[] + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination#cursor-based-pagination Cursor Docs} + * + * Sets the position for listing CatalogItems. + */ + cursor?: Prisma.CatalogItemWhereUniqueInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Take `±n` CatalogItems from the position of the cursor. + */ + take?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Skip the first `n` CatalogItems. + */ + skip?: number + distinct?: Prisma.CatalogItemScalarFieldEnum | Prisma.CatalogItemScalarFieldEnum[] +} + +/** + * CatalogItem create + */ +export type CatalogItemCreateArgs = { + /** + * Select specific fields to fetch from the CatalogItem + */ + select?: Prisma.CatalogItemSelect | null + /** + * Omit specific fields from the CatalogItem + */ + omit?: Prisma.CatalogItemOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: Prisma.CatalogItemInclude | null + /** + * The data needed to create a CatalogItem. + */ + data: Prisma.XOR +} + +/** + * CatalogItem createMany + */ +export type CatalogItemCreateManyArgs = { + /** + * The data used to create many CatalogItems. + */ + data: Prisma.CatalogItemCreateManyInput | Prisma.CatalogItemCreateManyInput[] + skipDuplicates?: boolean +} + +/** + * CatalogItem createManyAndReturn + */ +export type CatalogItemCreateManyAndReturnArgs = { + /** + * Select specific fields to fetch from the CatalogItem + */ + select?: Prisma.CatalogItemSelectCreateManyAndReturn | null + /** + * Omit specific fields from the CatalogItem + */ + omit?: Prisma.CatalogItemOmit | null + /** + * The data used to create many CatalogItems. + */ + data: Prisma.CatalogItemCreateManyInput | Prisma.CatalogItemCreateManyInput[] + skipDuplicates?: boolean +} + +/** + * CatalogItem update + */ +export type CatalogItemUpdateArgs = { + /** + * Select specific fields to fetch from the CatalogItem + */ + select?: Prisma.CatalogItemSelect | null + /** + * Omit specific fields from the CatalogItem + */ + omit?: Prisma.CatalogItemOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: Prisma.CatalogItemInclude | null + /** + * The data needed to update a CatalogItem. + */ + data: Prisma.XOR + /** + * Choose, which CatalogItem to update. + */ + where: Prisma.CatalogItemWhereUniqueInput +} + +/** + * CatalogItem updateMany + */ +export type CatalogItemUpdateManyArgs = { + /** + * The data used to update CatalogItems. + */ + data: Prisma.XOR + /** + * Filter which CatalogItems to update + */ + where?: Prisma.CatalogItemWhereInput + /** + * Limit how many CatalogItems to update. + */ + limit?: number +} + +/** + * CatalogItem updateManyAndReturn + */ +export type CatalogItemUpdateManyAndReturnArgs = { + /** + * Select specific fields to fetch from the CatalogItem + */ + select?: Prisma.CatalogItemSelectUpdateManyAndReturn | null + /** + * Omit specific fields from the CatalogItem + */ + omit?: Prisma.CatalogItemOmit | null + /** + * The data used to update CatalogItems. + */ + data: Prisma.XOR + /** + * Filter which CatalogItems to update + */ + where?: Prisma.CatalogItemWhereInput + /** + * Limit how many CatalogItems to update. + */ + limit?: number +} + +/** + * CatalogItem upsert + */ +export type CatalogItemUpsertArgs = { + /** + * Select specific fields to fetch from the CatalogItem + */ + select?: Prisma.CatalogItemSelect | null + /** + * Omit specific fields from the CatalogItem + */ + omit?: Prisma.CatalogItemOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: Prisma.CatalogItemInclude | null + /** + * The filter to search for the CatalogItem to update in case it exists. + */ + where: Prisma.CatalogItemWhereUniqueInput + /** + * In case the CatalogItem found by the `where` argument doesn't exist, create a new CatalogItem with this data. + */ + create: Prisma.XOR + /** + * In case the CatalogItem was found with the provided `where` argument, update it with this data. + */ + update: Prisma.XOR +} + +/** + * CatalogItem delete + */ +export type CatalogItemDeleteArgs = { + /** + * Select specific fields to fetch from the CatalogItem + */ + select?: Prisma.CatalogItemSelect | null + /** + * Omit specific fields from the CatalogItem + */ + omit?: Prisma.CatalogItemOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: Prisma.CatalogItemInclude | null + /** + * Filter which CatalogItem to delete. + */ + where: Prisma.CatalogItemWhereUniqueInput +} + +/** + * CatalogItem deleteMany + */ +export type CatalogItemDeleteManyArgs = { + /** + * Filter which CatalogItems to delete + */ + where?: Prisma.CatalogItemWhereInput + /** + * Limit how many CatalogItems to delete. + */ + limit?: number +} + +/** + * CatalogItem.linkedItems + */ +export type CatalogItem$linkedItemsArgs = { + /** + * Select specific fields to fetch from the CatalogItem + */ + select?: Prisma.CatalogItemSelect | null + /** + * Omit specific fields from the CatalogItem + */ + omit?: Prisma.CatalogItemOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: Prisma.CatalogItemInclude | null + where?: Prisma.CatalogItemWhereInput + orderBy?: Prisma.CatalogItemOrderByWithRelationInput | Prisma.CatalogItemOrderByWithRelationInput[] + cursor?: Prisma.CatalogItemWhereUniqueInput + take?: number + skip?: number + distinct?: Prisma.CatalogItemScalarFieldEnum | Prisma.CatalogItemScalarFieldEnum[] +} + +/** + * CatalogItem.linkedTo + */ +export type CatalogItem$linkedToArgs = { + /** + * Select specific fields to fetch from the CatalogItem + */ + select?: Prisma.CatalogItemSelect | null + /** + * Omit specific fields from the CatalogItem + */ + omit?: Prisma.CatalogItemOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: Prisma.CatalogItemInclude | null + where?: Prisma.CatalogItemWhereInput + orderBy?: Prisma.CatalogItemOrderByWithRelationInput | Prisma.CatalogItemOrderByWithRelationInput[] + cursor?: Prisma.CatalogItemWhereUniqueInput + take?: number + skip?: number + distinct?: Prisma.CatalogItemScalarFieldEnum | Prisma.CatalogItemScalarFieldEnum[] +} + +/** + * CatalogItem without action + */ +export type CatalogItemDefaultArgs = { + /** + * Select specific fields to fetch from the CatalogItem + */ + select?: Prisma.CatalogItemSelect | null + /** + * Omit specific fields from the CatalogItem + */ + omit?: Prisma.CatalogItemOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: Prisma.CatalogItemInclude | null +} diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 844d555..11cc770 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -82,6 +82,39 @@ model Company { updatedAt DateTime @updatedAt } +model CatalogItem { + id String @id @default(cuid()) + cwCatalogId Int @unique + name String + description String? + customerDescription String? + internalNotes String? + + linkedItems CatalogItem[] @relation("LinkedItems") + linkedTo CatalogItem[] @relation("LinkedItems") + + manufacturer String? + manufactureCwId Int? + + partNumber String? + + vendorName String? + vendorSku String? + vendorCwId Int? + + price Float + cost Float + + inactive Boolean @default(false) + salesTaxable Boolean @default(true) + + onHand Int @default(0) + cwLastUpdated DateTime? + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} + model CredentialType { id String @id @default(cuid()) name String @unique diff --git a/src/constants.ts b/src/constants.ts index a519e9f..d17a3a3 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -24,16 +24,23 @@ export const sessionDuration = 30 * 24 * 60 * 60000; export const accessTokenDuration = "10min"; export const refreshTokenDuration = "30d"; -export const accessTokenPrivateKey = - readFileSync(`.accessToken.key`).toString(); -export const refreshTokenPrivateKey = - readFileSync(`.refreshToken.key`).toString(); -export const permissionsPrivateKey = readFileSync(`.permissions.key`); -export const secureValuesPrivateKey = - readFileSync(`.secureValues.key`).toString(); -export const secureValuesPublicKey = readFileSync( - `public-keys/.secureValues.pub`, -).toString(); +const isProduction = process.env.NODE_ENV === "production"; + +export const accessTokenPrivateKey = isProduction + ? process.env.ACCESS_TOKEN_PRIVATE_KEY! + : readFileSync(`.accessToken.key`).toString(); +export const refreshTokenPrivateKey = isProduction + ? process.env.REFRESH_TOKEN_PRIVATE_KEY! + : readFileSync(`.refreshToken.key`).toString(); +export const permissionsPrivateKey = isProduction + ? process.env.PERMISSIONS_PRIVATE_KEY! + : readFileSync(`.permissions.key`).toString(); +export const secureValuesPrivateKey = isProduction + ? process.env.SECURE_VALUES_PRIVATE_KEY! + : readFileSync(`.secureValues.key`).toString(); +export const secureValuesPublicKey = isProduction + ? process.env.SECURE_VALUES_PUBLIC_KEY! + : readFileSync(`public-keys/.secureValues.pub`).toString(); // Microsoft Auth Constants const msalConfig: msal.Configuration = { diff --git a/src/index.ts b/src/index.ts index 06489bd..f79a1b2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,8 +1,10 @@ import { refresh } from "./api/auth"; import app from "./api/server"; -import { engine, PORT } from "./constants"; +import { engine, PORT, unifi, unifiPassword, unifiUsername } from "./constants"; import { unifiSites } from "./managers/unifiSites"; import { refreshCompanies } from "./modules/cw-utils/refreshCompanies"; +import { refreshCatalog } from "./modules/cw-utils/procurement/refreshCatalog"; +import { refreshInventory } from "./modules/cw-utils/procurement/refreshInventory"; import { events, setupEventDebugger } from "./modules/globalEvents"; // Setup global event debugger in non-production environments @@ -14,6 +16,21 @@ setInterval(() => { return refreshCompanies(); }, 60 * 1000); +// Refresh the internal catalog every minute +await refreshCatalog(); +setInterval(() => { + return refreshCatalog(); +}, 60 * 1000); + +// Refresh inventory on hand every 2 minutes +await refreshInventory(); +setInterval( + () => { + return refreshInventory(); + }, + 2 * 60 * 1000, +); + await unifiSites.syncSites(); setInterval(() => { return unifiSites.syncSites(); diff --git a/src/managers/unifiSites.ts b/src/managers/unifiSites.ts index 7d283d5..d7006d2 100644 --- a/src/managers/unifiSites.ts +++ b/src/managers/unifiSites.ts @@ -1,6 +1,7 @@ import { prisma, unifi, unifiUsername, unifiPassword } from "../constants"; import GenericError from "../Errors/GenericError"; import { UnifiSite } from "../../generated/prisma/client"; +import { events } from "../modules/globalEvents"; let loggedIn = false; @@ -16,6 +17,24 @@ async function ensureLoggedIn(): Promise { loggedIn = true; } +/** + * Wraps a UniFi API call with automatic re-authentication on failure. + * If the call fails and we were previously logged in (i.e. session likely + * expired), resets the login state, re-authenticates, and retries once. + */ +async function withReauth(fn: () => Promise): Promise { + await ensureLoggedIn(); + try { + return await fn(); + } catch (e) { + if (!loggedIn) throw e; + events.emit("unifi:reauth"); + loggedIn = false; + await ensureLoggedIn(); + return fn(); + } +} + export const unifiSites = { /** * Fetch a UniFi site record from the database by its internal ID. @@ -96,12 +115,14 @@ export const unifiSites = { * Creates new records for sites not yet tracked, updates names for existing ones. */ async syncSites(): Promise { - await ensureLoggedIn(); + events.emit("unifi:sites:sync:started"); // Fetch all sites from the controller - const allSites = await unifi.getAllSites(); + const allSites = await withReauth(() => unifi.getAllSites()); const results: UnifiSite[] = []; + let created = 0; + let updated = 0; for (const site of allSites) { const existing = await prisma.unifiSite.findFirst({ @@ -109,22 +130,30 @@ export const unifiSites = { }); if (existing) { - const updated = await prisma.unifiSite.update({ + const updatedSite = await prisma.unifiSite.update({ where: { id: existing.id }, data: { name: site.description }, }); - results.push(updated); + results.push(updatedSite); + updated++; } else { - const created = await prisma.unifiSite.create({ + const createdSite = await prisma.unifiSite.create({ data: { name: site.description, siteId: site.name, }, }); - results.push(created); + results.push(createdSite); + created++; } } + events.emit("unifi:sites:sync:completed", { + total: results.length, + created, + updated, + }); + return results; }, @@ -132,24 +161,21 @@ export const unifiSites = { * Get live site overview from the UniFi controller. */ async getSiteOverview(siteId: string) { - await ensureLoggedIn(); - return unifi.getSiteOverview(siteId); + return withReauth(() => unifi.getSiteOverview(siteId)); }, /** * Get live devices from the UniFi controller for a site. */ async getDevices(siteId: string) { - await ensureLoggedIn(); - return unifi.getDevices(siteId); + return withReauth(() => unifi.getDevices(siteId)); }, /** * Get live WiFi networks (WLANs) from the UniFi controller for a site. */ async getWlanConf(siteId: string) { - await ensureLoggedIn(); - return unifi.getWlanConf(siteId); + return withReauth(() => unifi.getWlanConf(siteId)); }, /** @@ -160,25 +186,21 @@ export const unifiSites = { wlanId: string, updates: Parameters[2], ) { - await ensureLoggedIn(); - return unifi.updateWlanConf(siteId, wlanId, updates); + return withReauth(() => unifi.updateWlanConf(siteId, wlanId, updates)); }, /** * Get live network configurations from the UniFi controller for a site. */ async getNetworks(siteId: string) { - await ensureLoggedIn(); - return unifi.getNetworks(siteId); + return withReauth(() => unifi.getNetworks(siteId)); }, /** * Create a new site on the UniFi controller and track it in the database. */ async createSite(description: string): Promise { - await ensureLoggedIn(); - - const created = await unifi.createSite(description); + const created = await withReauth(() => unifi.createSite(description)); return prisma.unifiSite.create({ data: { @@ -192,8 +214,7 @@ export const unifiSites = { * Get WLAN groups from the UniFi controller for a site. */ async getWlanGroups(siteId: string) { - await ensureLoggedIn(); - return unifi.getWlanGroups(siteId); + return withReauth(() => unifi.getWlanGroups(siteId)); }, /** @@ -203,16 +224,14 @@ export const unifiSites = { siteId: string, input: Parameters[1], ) { - await ensureLoggedIn(); - return unifi.createWlanGroup(siteId, input); + return withReauth(() => unifi.createWlanGroup(siteId, input)); }, /** * Get user groups (speed profiles) from the UniFi controller for a site. */ async getUserGroups(siteId: string) { - await ensureLoggedIn(); - return unifi.getUserGroups(siteId); + return withReauth(() => unifi.getUserGroups(siteId)); }, /** @@ -222,16 +241,14 @@ export const unifiSites = { siteId: string, input: Parameters[1], ) { - await ensureLoggedIn(); - return unifi.createUserGroup(siteId, input); + return withReauth(() => unifi.createUserGroup(siteId, input)); }, /** * Get AP groups from the UniFi controller for a site. */ async getApGroups(siteId: string) { - await ensureLoggedIn(); - return unifi.getApGroups(siteId); + return withReauth(() => unifi.getApGroups(siteId)); }, /** @@ -243,40 +260,37 @@ export const unifiSites = { deviceMacs: string[], forWlanconf: boolean = false, ) { - await ensureLoggedIn(); - return unifi.createApGroup(siteId, name, deviceMacs, forWlanconf); + return withReauth(() => + unifi.createApGroup(siteId, name, deviceMacs, forWlanconf), + ); }, /** * Update an existing AP group's device MACs on the UniFi controller. */ async updateApGroup(siteId: string, groupId: string, deviceMacs: string[]) { - await ensureLoggedIn(); - return unifi.updateApGroup(siteId, groupId, deviceMacs); + return withReauth(() => unifi.updateApGroup(siteId, groupId, deviceMacs)); }, /** * Get access points only from the UniFi controller for a site. */ async getAccessPoints(siteId: string) { - await ensureLoggedIn(); - return unifi.getAccessPoints(siteId); + return withReauth(() => unifi.getAccessPoints(siteId)); }, /** * Get WiFi SSID limits per AP per radio band. */ async getWifiLimits(siteId: string) { - await ensureLoggedIn(); - return unifi.getWifiLimits(siteId); + return withReauth(() => unifi.getWifiLimits(siteId)); }, /** * Get private pre-shared keys for a specific WLAN. */ async getPrivatePSKs(siteId: string, wlanId: string) { - await ensureLoggedIn(); - return unifi.getPrivatePSKs(siteId, wlanId); + return withReauth(() => unifi.getPrivatePSKs(siteId, wlanId)); }, /** @@ -287,7 +301,6 @@ export const unifiSites = { wlanId: string, psk: Parameters[2], ) { - await ensureLoggedIn(); - return unifi.createPrivatePSK(siteId, wlanId, psk); + return withReauth(() => unifi.createPrivatePSK(siteId, wlanId, psk)); }, }; diff --git a/src/modules/cw-utils/procurement/catalog.ts b/src/modules/cw-utils/procurement/catalog.ts new file mode 100644 index 0000000..a060b7d --- /dev/null +++ b/src/modules/cw-utils/procurement/catalog.ts @@ -0,0 +1,75 @@ +import { Collection } from "@discordjs/collection"; +import { connectWiseApi } from "../../../constants"; +import { CatalogItem } from "./catalog.types.ts"; + +export interface CatalogSummary { + id: number; + _info?: Record; +} + +export interface InventoryEntry { + id: number; + onHand: number; +} + +export const catalogCw = { + countItems: async (): Promise => { + const response = await connectWiseApi.get("/procurement/catalog/count"); + return response.data.count; + }, + fetchAllCatalogSummary: async (): Promise< + Collection + > => { + const allItems = new Collection(); + const pageSize = 1000; + + const count = await catalogCw.countItems(); + const totalPages = Math.ceil(count / pageSize); + + for (let page = 0; page < totalPages; page++) { + const response = await connectWiseApi.get( + `/procurement/catalog?page=${page + 1}&pageSize=${pageSize}&fields=id,_info`, + ); + const items: CatalogSummary[] = response.data; + + for (const item of items) { + allItems.set(item.id, item); + } + } + + return allItems; + }, + fetchInventoryOnHand: async (cwCatalogId: number): Promise => { + const response = await connectWiseApi.get( + `/procurement/catalog/${cwCatalogId}/inventory?fields=onHand`, + ); + const entries: InventoryEntry[] = response.data; + return entries.reduce((sum, e) => sum + (e.onHand || 0), 0); + }, + fetchAllItemsFromCw: async (): Promise> => { + const allItems = new Collection(); + const pageSize = 1000; + + const count = await catalogCw.countItems(); + const totalPages = Math.ceil(count / pageSize); + + for (let page = 0; page < totalPages; page++) { + const response = await connectWiseApi.get( + `/procurement/catalog?page=${page + 1}&pageSize=${pageSize}`, + ); + const items: CatalogItem[] = response.data; + + for (const item of items) { + allItems.set(item.id, item); + } + } + + return allItems; + }, + fetch: async (id: string): Promise => { + const response = await connectWiseApi.get( + `/procurement/catalog/items/${id}`, + ); + return response.data; + }, +}; diff --git a/src/modules/cw-utils/procurement/catalog.types.ts b/src/modules/cw-utils/procurement/catalog.types.ts new file mode 100644 index 0000000..ec80703 --- /dev/null +++ b/src/modules/cw-utils/procurement/catalog.types.ts @@ -0,0 +1,75 @@ +interface CWReference { + id: number; + name: string; + _info?: Record; +} + +interface CWVendorReference { + id: number; + identifier: string; + name: string; + _info?: Record; +} + +interface CWCustomField { + id: number; + caption: string; + type: string; + entryMethod: string; + numberOfDecimals: number; + value: unknown; + connectWiseId: string; + rowNum: number; + userDefinedFieldRecId: number; + podId: string; +} + +export interface CatalogItem { + id: number; + identifier: string; + description: string; + inactiveFlag: boolean; + subcategory: CWReference; + type: CWReference; + productClass: string; + serializedFlag: boolean; + serializedCostFlag: boolean; + phaseProductFlag: boolean; + unitOfMeasure: CWReference; + minStockLevel: number; + price: number; + cost: number; + priceAttribute: string; + taxableFlag: boolean; + dropShipFlag: boolean; + specialOrderFlag: boolean; + customerDescription: string; + manufacturer: CWReference; + manufacturerPartNumber: string; + vendor: CWVendorReference; + vendorSku: string; + notes: string; + integrationXRef: string; + sla: CWReference; + entityType: CWReference; + recurringFlag: boolean; + recurringRevenue: number; + recurringCost: number; + recurringOneTimeFlag: boolean; + recurringBillCycle: CWReference; + recurringCycleType: string; + calculatedPriceFlag: boolean; + calculatedCostFlag: boolean; + category: CWReference; + calculatedPrice: number; + calculatedCost: number; + billableOption: string; + connectWiseID: string; + agreementType: CWReference; + markupPercentage: number; + markupFlag: boolean; + autoUpdateUnitCostFlag: boolean; + autoUpdateUnitPriceFlag: boolean; + _info?: Record; + customFields?: CWCustomField[]; +} diff --git a/src/modules/cw-utils/procurement/refreshCatalog.ts b/src/modules/cw-utils/procurement/refreshCatalog.ts new file mode 100644 index 0000000..8ed7134 --- /dev/null +++ b/src/modules/cw-utils/procurement/refreshCatalog.ts @@ -0,0 +1,140 @@ +import { prisma } from "../../../constants"; +import { events } from "../../globalEvents"; +import { catalogCw } from "./catalog"; + +export const refreshCatalog = async () => { + events.emit("cw:catalog:refresh:check"); + + // 1. Fetch lightweight summaries from CW (id + _info with lastUpdated) + const cwSummaries = await catalogCw.fetchAllCatalogSummary(); + + // 2. Fetch all DB items with their cwCatalogId and cwLastUpdated + const dbItems = await prisma.catalogItem.findMany({ + select: { cwCatalogId: true, cwLastUpdated: true }, + }); + const dbMap = new Map( + dbItems.map((item) => [item.cwCatalogId, item.cwLastUpdated]), + ); + + // 3. Compare CW lastUpdated vs DB cwLastUpdated — collect IDs that are stale or new + const staleIds: number[] = []; + + for (const [cwId, summary] of cwSummaries) { + const cwLastUpdated = summary._info?.lastUpdated + ? new Date(summary._info.lastUpdated) + : null; + const dbLastUpdated = dbMap.get(cwId) ?? null; + + // New item (not in DB) or CW has a newer timestamp + if (!dbLastUpdated || (cwLastUpdated && cwLastUpdated > dbLastUpdated)) { + staleIds.push(cwId); + } + } + + if (staleIds.length === 0) { + events.emit("cw:catalog:refresh:skipped", { + totalCw: cwSummaries.size, + totalDb: dbItems.length, + staleCount: 0, + }); + return; + } + + events.emit("cw:catalog:refresh:started", { + totalCw: cwSummaries.size, + totalDb: dbItems.length, + staleCount: staleIds.length, + }); + + // 4. Fetch full catalog data, then filter to only stale items + const staleIdSet = new Set(staleIds); + const allCwItems = await catalogCw.fetchAllItemsFromCw(); + const allStaleItems = new Map(); + + for (const [id, item] of allCwItems) { + if (staleIdSet.has(id)) { + allStaleItems.set(id, item); + } + } + + // 5. Batch fetch inventory onHand for stale items (50 concurrent) + const onHandMap = new Map(); + const batchSize = 50; + + for (let i = 0; i < staleIds.length; i += batchSize) { + const batch = staleIds.slice(i, i + batchSize); + await Promise.all( + batch.map(async (cwId) => { + try { + const onHand = await catalogCw.fetchInventoryOnHand(cwId); + onHandMap.set(cwId, onHand); + } catch { + onHandMap.set(cwId, 0); + } + }), + ); + } + + // 6. Upsert only the stale/new items + const updatedCount = ( + await Promise.all( + staleIds.map(async (cwId) => { + const item = allStaleItems.get(cwId); + if (!item) return null; + + const cwLastUpdated = item._info?.lastUpdated + ? new Date(item._info.lastUpdated) + : new Date(); + const onHand = onHandMap.get(cwId) ?? 0; + + return await prisma.catalogItem.upsert({ + where: { cwCatalogId: cwId }, + create: { + cwCatalogId: cwId, + name: item.description, + description: item.description, + customerDescription: item.customerDescription, + internalNotes: item.notes, + manufacturer: item.manufacturer?.name, + manufactureCwId: item.manufacturer?.id, + partNumber: item.manufacturerPartNumber, + vendorName: item.vendor?.name, + vendorSku: item.vendorSku, + vendorCwId: item.vendor?.id, + price: item.price, + cost: item.cost, + inactive: item.inactiveFlag, + salesTaxable: item.taxableFlag, + onHand, + cwLastUpdated, + }, + update: { + name: item.description, + description: item.description, + customerDescription: item.customerDescription, + internalNotes: item.notes, + manufacturer: item.manufacturer?.name, + manufactureCwId: item.manufacturer?.id, + partNumber: item.manufacturerPartNumber, + vendorName: item.vendor?.name, + vendorSku: item.vendorSku, + vendorCwId: item.vendor?.id, + price: item.price, + cost: item.cost, + inactive: item.inactiveFlag, + salesTaxable: item.taxableFlag, + onHand, + cwLastUpdated, + }, + }); + }), + ) + ).filter(Boolean).length; + + events.emit("cw:catalog:refresh:completed", { + totalCw: cwSummaries.size, + totalDb: dbItems.length, + staleCount: staleIds.length, + itemsUpdated: updatedCount, + }); +}; diff --git a/src/modules/cw-utils/procurement/refreshInventory.ts b/src/modules/cw-utils/procurement/refreshInventory.ts new file mode 100644 index 0000000..5c642b9 --- /dev/null +++ b/src/modules/cw-utils/procurement/refreshInventory.ts @@ -0,0 +1,74 @@ +import { prisma } from "../../../constants"; +import { events } from "../../globalEvents"; +import { catalogCw } from "./catalog"; + +export const refreshInventory = async () => { + events.emit("cw:inventory:refresh:check"); + + // 1. Get all active catalog items from DB + const dbItems = await prisma.catalogItem.findMany({ + where: { inactive: false }, + select: { cwCatalogId: true, onHand: true }, + }); + + if (dbItems.length === 0) { + events.emit("cw:inventory:refresh:skipped", { + totalItems: 0, + updatedCount: 0, + }); + return; + } + + events.emit("cw:inventory:refresh:started", { + totalItems: dbItems.length, + }); + + // 2. Batch fetch inventory onHand for all items (50 concurrent) + const onHandMap = new Map(); + const batchSize = 150; + + for (let i = 0; i < dbItems.length; i += batchSize) { + const batch = dbItems.slice(i, i + batchSize); + await Promise.all( + batch.map(async (item) => { + try { + const onHand = await catalogCw.fetchInventoryOnHand(item.cwCatalogId); + onHandMap.set(item.cwCatalogId, onHand); + } catch { + onHandMap.set(item.cwCatalogId, item.onHand); + } + }), + ); + } + + // 3. Only update items where onHand has changed + const updates = dbItems.filter((item) => { + const newOnHand = onHandMap.get(item.cwCatalogId) ?? item.onHand; + return newOnHand !== item.onHand; + }); + + if (updates.length === 0) { + events.emit("cw:inventory:refresh:skipped", { + totalItems: dbItems.length, + updatedCount: 0, + }); + return; + } + + const updatedCount = ( + await Promise.all( + updates.map(async (item) => { + const newOnHand = onHandMap.get(item.cwCatalogId) ?? item.onHand; + return await prisma.catalogItem.update({ + where: { cwCatalogId: item.cwCatalogId }, + data: { onHand: newOnHand }, + }); + }), + ) + ).length; + + events.emit("cw:inventory:refresh:completed", { + totalItems: dbItems.length, + updatedCount, + }); +}; diff --git a/src/modules/globalEvents.ts b/src/modules/globalEvents.ts index 9b4514c..a32cce8 100644 --- a/src/modules/globalEvents.ts +++ b/src/modules/globalEvents.ts @@ -108,6 +108,56 @@ interface EventTypes { company: CompanyController; updatedFields: Partial; }) => void; + + // ConnectWise Catalog Events + "cw:catalog:refresh:check": () => void; + "cw:catalog:refresh:started": (data: { + totalCw: number; + totalDb: number; + staleCount: number; + }) => void; + "cw:catalog:refresh:completed": (data: { + totalCw: number; + totalDb: number; + staleCount: number; + itemsUpdated: number; + }) => void; + "cw:catalog:refresh:skipped": (data: { + totalCw: number; + totalDb: number; + staleCount: number; + }) => void; + + // UniFi Events + "unifi:login:ok": (data: { + type: "unifi-os" | "legacy"; + status: number; + }) => void; + "unifi:login:fallback": () => void; + "unifi:reauth": () => void; + "unifi:sites:sync:started": () => void; + "unifi:sites:sync:completed": (data: { + total: number; + created: number; + updated: number; + }) => void; + "unifi:wlan:fetched": (data: { path: string }) => void; + "unifi:wlan:fetch_failed": (data: { + path: string; + status: number | unknown; + }) => void; + + // ConnectWise Inventory Events + "cw:inventory:refresh:check": () => void; + "cw:inventory:refresh:started": (data: { totalItems: number }) => void; + "cw:inventory:refresh:completed": (data: { + totalItems: number; + updatedCount: number; + }) => void; + "cw:inventory:refresh:skipped": (data: { + totalItems: number; + updatedCount: number; + }) => void; } export const events = new Eventra(); diff --git a/src/modules/unifi-api/UnifiClient.ts b/src/modules/unifi-api/UnifiClient.ts index 207a272..3c19189 100644 --- a/src/modules/unifi-api/UnifiClient.ts +++ b/src/modules/unifi-api/UnifiClient.ts @@ -1,5 +1,6 @@ import axios, { AxiosInstance } from "axios"; import https from "https"; +import { events } from "../globalEvents"; import { ApGroup, ApRadioWifiUsage, @@ -57,13 +58,13 @@ export class UnifiClient { try { // UniFi OS const res = await this.client.post("/api/auth/login", body); - console.log("Login OK (UniFi OS)", res.status); + events.emit("unifi:login:ok", { type: "unifi-os", status: res.status }); this.persistSession(res); } catch (e) { // Legacy controller - console.log("UniFi OS login failed, trying legacy..."); + events.emit("unifi:login:fallback"); const res = await this.client.post("/api/login", body); - console.log("Login OK (legacy)", res.status); + events.emit("unifi:login:ok", { type: "legacy", status: res.status }); this.persistSession(res); } } @@ -78,13 +79,13 @@ export class UnifiClient { try { const res = await this.client.get(path); const data = (res.data?.data ?? res.data) as WlanConfRaw[]; - console.log(`Fetched wlan from ${path}`); + events.emit("unifi:wlan:fetched", { path }); return data; } catch (e) { - console.log( - `Failed ${path}:`, - axios.isAxiosError(e) ? e.response?.status : e, - ); + events.emit("unifi:wlan:fetch_failed", { + path, + status: axios.isAxiosError(e) ? e.response?.status : e, + }); } } diff --git a/test-catalog-info.ts b/test-catalog-info.ts new file mode 100644 index 0000000..03a1c7b --- /dev/null +++ b/test-catalog-info.ts @@ -0,0 +1,71 @@ +import axios from "axios"; + +const connectWiseApi = axios.create({ + baseURL: `https://ttscw.totaltech.net/v4_6_release/apis/3.0/`, + headers: { + Authorization: `Basic ${process.env.CW_BASIC_TOKEN}`, + clientId: `${process.env.CW_CLIENT_ID}`, + "Content-Type": "application/json", + }, +}); + +async function main() { + // Fetch inactive catalog items + const pageSize = 1000; + let page = 1; + const inactiveItems: any[] = []; + + while (true) { + const response = await connectWiseApi.get( + `/procurement/catalog?page=${page}&pageSize=${pageSize}&conditions=inactiveFlag=true&fields=id,identifier,description,_info`, + ); + if (response.data.length === 0) break; + inactiveItems.push(...response.data); + page++; + } + + console.log(`Found ${inactiveItems.length} inactive catalog items`); + console.log(`Checking inventory for each (batches of 50)...\n`); + + const withStock: any[] = []; + const batchSize = 50; + + for (let i = 0; i < inactiveItems.length; i += batchSize) { + const batch = inactiveItems.slice(i, i + batchSize); + await Promise.all( + batch.map(async (item) => { + try { + const res = await connectWiseApi.get( + `/procurement/catalog/${item.id}/inventory?fields=onHand`, + ); + const totalOnHand = (res.data as { onHand: number }[]).reduce( + (sum, e) => sum + (e.onHand || 0), + 0, + ); + if (totalOnHand > 0) { + withStock.push({ + id: item.id, + identifier: item.identifier, + description: item.description, + totalOnHand, + }); + } + } catch {} + }), + ); + const done = Math.min(i + batchSize, inactiveItems.length); + if (done % 500 === 0 || done === inactiveItems.length) { + console.log(` ${done}/${inactiveItems.length} checked`); + } + } + + console.log( + `\nInactive items with inventory: ${withStock.length}/${inactiveItems.length}\n`, + ); + + if (withStock.length > 0) { + console.log(JSON.stringify(withStock, null, 2)); + } +} + +main().catch(console.error); diff --git a/tsconfig.json b/tsconfig.json index eff676a..fd029e8 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,6 +2,7 @@ "compilerOptions": { // Environment setup & latest features "lib": ["ESNext"], + "types": ["bun"], "target": "ESNext", "module": "Preserve", "moduleDetection": "force", diff --git a/utils/genProductionKeys.ts b/utils/genProductionKeys.ts new file mode 100644 index 0000000..fcdf786 --- /dev/null +++ b/utils/genProductionKeys.ts @@ -0,0 +1,62 @@ +import keypair from "keypair"; +import { mkdirSync } from "fs"; + +const outputDir = "production-keys"; + +console.log(` +Generating Production Keys +----------------- +This script will generate all RSA key pairs needed for the production deployment. +Output directory: ${outputDir}/ +-----------------`); + +// Ensure output directory exists +mkdirSync(outputDir, { recursive: true }); + +const keyFiles = ["accessToken", "refreshToken", "permissions", "secureValues"]; + +const generatedKeys: Record = {}; + +for (const name of keyFiles) { + console.log(`Generating '${name}' key pair (4096-bit RSA)...`); + const keys = keypair({ bits: 4096 }); + generatedKeys[name] = keys; + + const privPath = `${outputDir}/${name}.key`; + const pubPath = `${outputDir}/${name}.pub`; + + await Bun.write(privPath, keys.private); + await Bun.write(pubPath, keys.public); + + console.log(` ✔ ${privPath}`); + console.log(` ✔ ${pubPath}`); +} + +// Generate Kubernetes Secret YAML +const toBase64 = (str: string) => Buffer.from(str).toString("base64"); + +const secretYaml = `apiVersion: v1 +kind: Secret +metadata: + name: ttscm-keys +type: Opaque +data: + accessToken.key: ${toBase64(generatedKeys["accessToken"].private)} + refreshToken.key: ${toBase64(generatedKeys["refreshToken"].private)} + permissions.key: ${toBase64(generatedKeys["permissions"].private)} + secureValues.key: ${toBase64(generatedKeys["secureValues"].private)} + secureValues.pub: ${toBase64(generatedKeys["secureValues"].public)} +`; + +const secretPath = `${outputDir}/ttscm-keys-secret.yaml`; +await Bun.write(secretPath, secretYaml); +console.log(`\n ✔ ${secretPath}`); + +console.log(` +----------------- +All production keys and K8s Secret manifest generated in '${outputDir}/'. + +⚠️ Delete the '${outputDir}/' directory after applying to your cluster. + Do NOT commit these keys to version control. +----------------- +`);