
- Убран текст "(с рецептурой)" из названий товаров в корзине - Добавлен раздел 9.2.6 в rules-complete.md с единым стандартом корзины - Определены обязательные размеры, структура и функциональность - Запрещено отображение технических суффиксов в UI корзины 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1381 lines
35 KiB
TypeScript
1381 lines
35 KiB
TypeScript
import { gql } from 'graphql-tag'
|
||
|
||
export const typeDefs = gql`
|
||
scalar DateTime
|
||
|
||
type Query {
|
||
me: User
|
||
organization(id: ID!): Organization
|
||
|
||
# Поиск организаций по типу для добавления в контрагенты
|
||
searchOrganizations(type: OrganizationType, search: String): [Organization!]!
|
||
|
||
# Мои контрагенты
|
||
myCounterparties: [Organization!]!
|
||
|
||
# Поставщики поставок
|
||
supplySuppliers: [SupplySupplier!]!
|
||
|
||
# Логистика организации
|
||
organizationLogistics(organizationId: ID!): [Logistics!]!
|
||
|
||
# Входящие заявки
|
||
incomingRequests: [CounterpartyRequest!]!
|
||
|
||
# Исходящие заявки
|
||
outgoingRequests: [CounterpartyRequest!]!
|
||
|
||
# Сообщения с контрагентом
|
||
messages(counterpartyId: ID!, limit: Int, offset: Int): [Message!]!
|
||
|
||
# Список чатов (последние сообщения с каждым контрагентом)
|
||
conversations: [Conversation!]!
|
||
|
||
# Услуги организации
|
||
myServices: [Service!]!
|
||
|
||
# Расходники селлеров (материалы клиентов)
|
||
mySupplies: [Supply!]!
|
||
|
||
# Доступные расходники для рецептур селлеров (только с ценой и в наличии)
|
||
getAvailableSuppliesForRecipe: [SupplyForRecipe!]!
|
||
|
||
# Расходники фулфилмента (материалы для работы фулфилмента)
|
||
myFulfillmentSupplies: [Supply!]!
|
||
|
||
# Расходники селлеров на складе фулфилмента (только для фулфилмента)
|
||
sellerSuppliesOnWarehouse: [Supply!]!
|
||
|
||
# Заказы поставок расходников
|
||
supplyOrders: [SupplyOrder!]!
|
||
|
||
# Счетчик поставок, требующих одобрения
|
||
pendingSuppliesCount: PendingSuppliesCount!
|
||
|
||
# Логистика организации
|
||
myLogistics: [Logistics!]!
|
||
|
||
# Логистические партнеры (организации-логисты)
|
||
logisticsPartners: [Organization!]!
|
||
|
||
# Поставки Wildberries
|
||
myWildberriesSupplies: [WildberriesSupply!]!
|
||
|
||
# Товары поставщика
|
||
myProducts: [Product!]!
|
||
|
||
# Товары на складе фулфилмента
|
||
warehouseProducts: [Product!]!
|
||
|
||
# Все товары всех поставщиков для маркета
|
||
allProducts(search: String, category: String): [Product!]!
|
||
|
||
# Товары конкретной организации (для формы создания поставки)
|
||
organizationProducts(organizationId: ID!, search: String, category: String, type: String): [Product!]!
|
||
|
||
# Все категории
|
||
categories: [Category!]!
|
||
|
||
# Корзина пользователя
|
||
myCart: Cart
|
||
|
||
# Избранные товары пользователя
|
||
myFavorites: [Product!]!
|
||
|
||
# Сотрудники организации
|
||
myEmployees: [Employee!]!
|
||
employee(id: ID!): Employee
|
||
|
||
# Табель сотрудника за месяц
|
||
employeeSchedule(employeeId: ID!, year: Int!, month: Int!): [EmployeeSchedule!]!
|
||
|
||
# Публичные услуги контрагента (для фулфилмента)
|
||
counterpartyServices(organizationId: ID!): [Service!]!
|
||
|
||
# Публичные расходники контрагента (для поставщиков)
|
||
counterpartySupplies(organizationId: ID!): [Supply!]!
|
||
|
||
# Админ запросы
|
||
adminMe: Admin
|
||
allUsers(search: String, limit: Int, offset: Int): UsersResponse!
|
||
|
||
# Wildberries статистика
|
||
getWildberriesStatistics(period: String, startDate: String, endDate: String): WildberriesStatisticsResponse!
|
||
|
||
# Отладка рекламы (временно)
|
||
debugWildberriesAdverts: DebugAdvertsResponse!
|
||
|
||
# Статистика кампаний Wildberries
|
||
getWildberriesCampaignStats(input: WildberriesCampaignStatsInput!): WildberriesCampaignStatsResponse!
|
||
|
||
# Список кампаний Wildberries
|
||
getWildberriesCampaignsList: WildberriesCampaignsListResponse!
|
||
|
||
# Заявки покупателей на возврат от Wildberries (для фулфилмента)
|
||
wbReturnClaims(isArchive: Boolean!, limit: Int, offset: Int): WbReturnClaimsResponse!
|
||
|
||
# Типы для внешней рекламы
|
||
getExternalAds(dateFrom: String!, dateTo: String!): ExternalAdsResponse!
|
||
|
||
# Типы для кеша склада WB
|
||
getWBWarehouseData: WBWarehouseCacheResponse!
|
||
}
|
||
|
||
type Mutation {
|
||
# Авторизация через SMS
|
||
sendSmsCode(phone: String!): SmsResponse!
|
||
verifySmsCode(phone: String!, code: String!): AuthResponse!
|
||
|
||
# Валидация ИНН
|
||
verifyInn(inn: String!): InnValidationResponse!
|
||
|
||
# Обновление профиля пользователя
|
||
updateUserProfile(input: UpdateUserProfileInput!): UpdateUserProfileResponse!
|
||
|
||
# Обновление данных организации по ИНН
|
||
updateOrganizationByInn(inn: String!): UpdateOrganizationResponse!
|
||
|
||
# Регистрация организации
|
||
registerFulfillmentOrganization(input: FulfillmentRegistrationInput!): AuthResponse!
|
||
registerSellerOrganization(input: SellerRegistrationInput!): AuthResponse!
|
||
|
||
# Работа с API ключами
|
||
addMarketplaceApiKey(input: MarketplaceApiKeyInput!): ApiKeyResponse!
|
||
removeMarketplaceApiKey(marketplace: MarketplaceType!): Boolean!
|
||
|
||
# Выход из системы
|
||
logout: Boolean!
|
||
|
||
# Работа с контрагентами
|
||
sendCounterpartyRequest(organizationId: ID!, message: String): CounterpartyRequestResponse!
|
||
respondToCounterpartyRequest(requestId: ID!, accept: Boolean!): CounterpartyRequestResponse!
|
||
cancelCounterpartyRequest(requestId: ID!): Boolean!
|
||
removeCounterparty(organizationId: ID!): Boolean!
|
||
|
||
# Работа с сообщениями
|
||
sendMessage(receiverOrganizationId: ID!, content: String, type: MessageType = TEXT): MessageResponse!
|
||
sendVoiceMessage(receiverOrganizationId: ID!, voiceUrl: String!, voiceDuration: Int!): MessageResponse!
|
||
sendImageMessage(
|
||
receiverOrganizationId: ID!
|
||
fileUrl: String!
|
||
fileName: String!
|
||
fileSize: Int!
|
||
fileType: String!
|
||
): MessageResponse!
|
||
sendFileMessage(
|
||
receiverOrganizationId: ID!
|
||
fileUrl: String!
|
||
fileName: String!
|
||
fileSize: Int!
|
||
fileType: String!
|
||
): MessageResponse!
|
||
markMessagesAsRead(conversationId: ID!): Boolean!
|
||
|
||
# Работа с услугами
|
||
createService(input: ServiceInput!): ServiceResponse!
|
||
updateService(id: ID!, input: ServiceInput!): ServiceResponse!
|
||
deleteService(id: ID!): Boolean!
|
||
|
||
# Работа с расходниками (только обновление цены разрешено)
|
||
updateSupplyPrice(id: ID!, input: UpdateSupplyPriceInput!): SupplyResponse!
|
||
|
||
# Использование расходников фулфилмента
|
||
useFulfillmentSupplies(input: UseFulfillmentSuppliesInput!): SupplyResponse!
|
||
|
||
# Заказы поставок расходников
|
||
createSupplyOrder(input: SupplyOrderInput!): SupplyOrderResponse!
|
||
updateSupplyOrderStatus(id: ID!, status: SupplyOrderStatus!): SupplyOrderResponse!
|
||
|
||
# Назначение логистики фулфилментом
|
||
assignLogisticsToSupply(supplyOrderId: ID!, logisticsPartnerId: ID!, responsibleId: ID): SupplyOrderResponse!
|
||
|
||
# Действия поставщика
|
||
supplierApproveOrder(id: ID!): SupplyOrderResponse!
|
||
supplierRejectOrder(id: ID!, reason: String): SupplyOrderResponse!
|
||
supplierShipOrder(id: ID!): SupplyOrderResponse!
|
||
|
||
# Действия логиста
|
||
logisticsConfirmOrder(id: ID!): SupplyOrderResponse!
|
||
logisticsRejectOrder(id: ID!, reason: String): SupplyOrderResponse!
|
||
|
||
# Действия фулфилмента
|
||
fulfillmentReceiveOrder(id: ID!): SupplyOrderResponse!
|
||
|
||
# Работа с логистикой
|
||
createLogistics(input: LogisticsInput!): LogisticsResponse!
|
||
updateLogistics(id: ID!, input: LogisticsInput!): LogisticsResponse!
|
||
deleteLogistics(id: ID!): Boolean!
|
||
|
||
# Работа с товарами (для поставщиков)
|
||
createProduct(input: ProductInput!): ProductResponse!
|
||
updateProduct(id: ID!, input: ProductInput!): ProductResponse!
|
||
deleteProduct(id: ID!): Boolean!
|
||
|
||
# Валидация и управление остатками товаров
|
||
checkArticleUniqueness(article: String!, excludeId: ID): ArticleUniquenessResponse!
|
||
reserveProductStock(productId: ID!, quantity: Int!): ProductStockResponse!
|
||
releaseProductReserve(productId: ID!, quantity: Int!): ProductStockResponse!
|
||
updateProductInTransit(productId: ID!, quantity: Int!, operation: String!): ProductStockResponse!
|
||
|
||
# Работа с категориями
|
||
createCategory(input: CategoryInput!): CategoryResponse!
|
||
updateCategory(id: ID!, input: CategoryInput!): CategoryResponse!
|
||
deleteCategory(id: ID!): Boolean!
|
||
|
||
# Работа с корзиной
|
||
addToCart(productId: ID!, quantity: Int = 1): CartResponse!
|
||
updateCartItem(productId: ID!, quantity: Int!): CartResponse!
|
||
removeFromCart(productId: ID!): CartResponse!
|
||
clearCart: Boolean!
|
||
|
||
# Работа с избранным
|
||
addToFavorites(productId: ID!): FavoritesResponse!
|
||
removeFromFavorites(productId: ID!): FavoritesResponse!
|
||
|
||
# Работа с сотрудниками
|
||
createEmployee(input: CreateEmployeeInput!): EmployeeResponse!
|
||
updateEmployee(id: ID!, input: UpdateEmployeeInput!): EmployeeResponse!
|
||
deleteEmployee(id: ID!): Boolean!
|
||
updateEmployeeSchedule(input: UpdateScheduleInput!): Boolean!
|
||
|
||
# Работа с поставками Wildberries
|
||
createWildberriesSupply(input: CreateWildberriesSupplyInput!): WildberriesSupplyResponse!
|
||
updateWildberriesSupply(id: ID!, input: UpdateWildberriesSupplyInput!): WildberriesSupplyResponse!
|
||
deleteWildberriesSupply(id: ID!): Boolean!
|
||
|
||
# Работа с поставщиками для поставок
|
||
createSupplySupplier(input: CreateSupplySupplierInput!): SupplySupplierResponse!
|
||
|
||
# Админ мутации
|
||
adminLogin(username: String!, password: String!): AdminAuthResponse!
|
||
adminLogout: Boolean!
|
||
|
||
# Типы для внешней рекламы
|
||
createExternalAd(input: ExternalAdInput!): ExternalAdResponse!
|
||
updateExternalAd(id: ID!, input: ExternalAdInput!): ExternalAdResponse!
|
||
deleteExternalAd(id: ID!): ExternalAdResponse!
|
||
updateExternalAdClicks(id: ID!, clicks: Int!): ExternalAdResponse!
|
||
}
|
||
|
||
# Типы данных
|
||
type User {
|
||
id: ID!
|
||
phone: String!
|
||
avatar: String
|
||
managerName: String
|
||
organization: Organization
|
||
createdAt: DateTime!
|
||
updatedAt: DateTime!
|
||
}
|
||
|
||
type Organization {
|
||
id: ID!
|
||
inn: String!
|
||
kpp: String
|
||
name: String
|
||
fullName: String
|
||
address: String
|
||
addressFull: String
|
||
ogrn: String
|
||
ogrnDate: DateTime
|
||
type: OrganizationType!
|
||
market: String
|
||
status: String
|
||
actualityDate: DateTime
|
||
registrationDate: DateTime
|
||
liquidationDate: DateTime
|
||
managementName: String
|
||
managementPost: String
|
||
opfCode: String
|
||
opfFull: String
|
||
opfShort: String
|
||
okato: String
|
||
oktmo: String
|
||
okpo: String
|
||
okved: String
|
||
employeeCount: Int
|
||
revenue: String
|
||
taxSystem: String
|
||
phones: JSON
|
||
emails: JSON
|
||
users: [User!]!
|
||
apiKeys: [ApiKey!]!
|
||
services: [Service!]!
|
||
supplies: [Supply!]!
|
||
isCounterparty: Boolean
|
||
isCurrentUser: Boolean
|
||
hasOutgoingRequest: Boolean
|
||
hasIncomingRequest: Boolean
|
||
createdAt: DateTime!
|
||
updatedAt: DateTime!
|
||
}
|
||
|
||
type ApiKey {
|
||
id: ID!
|
||
marketplace: MarketplaceType!
|
||
apiKey: String!
|
||
isActive: Boolean!
|
||
validationData: JSON
|
||
createdAt: DateTime!
|
||
updatedAt: DateTime!
|
||
}
|
||
|
||
# Входные типы для мутаций
|
||
input UpdateUserProfileInput {
|
||
# Аватар пользователя
|
||
avatar: String
|
||
|
||
# Контактные данные организации
|
||
orgPhone: String
|
||
managerName: String
|
||
telegram: String
|
||
whatsapp: String
|
||
email: String
|
||
|
||
# Банковские данные
|
||
bankName: String
|
||
bik: String
|
||
accountNumber: String
|
||
corrAccount: String
|
||
|
||
# Рынок для поставщиков
|
||
market: String
|
||
}
|
||
|
||
input FulfillmentRegistrationInput {
|
||
phone: String!
|
||
inn: String!
|
||
type: OrganizationType!
|
||
}
|
||
|
||
input SellerRegistrationInput {
|
||
phone: String!
|
||
wbApiKey: String
|
||
ozonApiKey: String
|
||
ozonClientId: String
|
||
}
|
||
|
||
input MarketplaceApiKeyInput {
|
||
marketplace: MarketplaceType!
|
||
apiKey: String!
|
||
clientId: String # Для Ozon
|
||
validateOnly: Boolean # Только валидация без сохранения
|
||
}
|
||
|
||
# Ответные типы
|
||
type SmsResponse {
|
||
success: Boolean!
|
||
message: String!
|
||
}
|
||
|
||
type AuthResponse {
|
||
success: Boolean!
|
||
message: String!
|
||
token: String
|
||
user: User
|
||
}
|
||
|
||
type InnValidationResponse {
|
||
success: Boolean!
|
||
message: String!
|
||
organization: ValidatedOrganization
|
||
}
|
||
|
||
type ValidatedOrganization {
|
||
name: String!
|
||
fullName: String!
|
||
address: String!
|
||
isActive: Boolean!
|
||
}
|
||
|
||
type ApiKeyResponse {
|
||
success: Boolean!
|
||
message: String!
|
||
apiKey: ApiKey
|
||
}
|
||
|
||
type UpdateUserProfileResponse {
|
||
success: Boolean!
|
||
message: String!
|
||
user: User
|
||
}
|
||
|
||
type UpdateOrganizationResponse {
|
||
success: Boolean!
|
||
message: String!
|
||
user: User
|
||
}
|
||
|
||
# Enums
|
||
enum OrganizationType {
|
||
FULFILLMENT
|
||
SELLER
|
||
LOGIST
|
||
WHOLESALE
|
||
}
|
||
|
||
enum MarketplaceType {
|
||
WILDBERRIES
|
||
OZON
|
||
}
|
||
|
||
# ProductType теперь String, чтобы поддерживать кириллические значения из БД
|
||
# Возможные значения: "ТОВАР", "БРАК", "РАСХОДНИКИ", "ПРОДУКТ"
|
||
|
||
enum CounterpartyRequestStatus {
|
||
PENDING
|
||
ACCEPTED
|
||
REJECTED
|
||
CANCELLED
|
||
}
|
||
|
||
# Типы для контрагентов
|
||
type CounterpartyRequest {
|
||
id: ID!
|
||
status: CounterpartyRequestStatus!
|
||
message: String
|
||
sender: Organization!
|
||
receiver: Organization!
|
||
createdAt: DateTime!
|
||
updatedAt: DateTime!
|
||
}
|
||
|
||
type CounterpartyRequestResponse {
|
||
success: Boolean!
|
||
message: String!
|
||
request: CounterpartyRequest
|
||
}
|
||
|
||
# Типы для сообщений
|
||
type Message {
|
||
id: ID!
|
||
content: String
|
||
type: MessageType
|
||
voiceUrl: String
|
||
voiceDuration: Int
|
||
fileUrl: String
|
||
fileName: String
|
||
fileSize: Int
|
||
fileType: String
|
||
senderId: ID!
|
||
senderOrganization: Organization!
|
||
receiverOrganization: Organization!
|
||
isRead: Boolean!
|
||
createdAt: DateTime!
|
||
updatedAt: DateTime!
|
||
}
|
||
|
||
enum MessageType {
|
||
TEXT
|
||
VOICE
|
||
IMAGE
|
||
FILE
|
||
}
|
||
|
||
type Conversation {
|
||
id: ID!
|
||
counterparty: Organization!
|
||
lastMessage: Message
|
||
unreadCount: Int!
|
||
updatedAt: DateTime!
|
||
}
|
||
|
||
type MessageResponse {
|
||
success: Boolean!
|
||
message: String!
|
||
messageData: Message
|
||
}
|
||
|
||
# Типы для услуг
|
||
type Service {
|
||
id: ID!
|
||
name: String!
|
||
description: String
|
||
price: Float!
|
||
imageUrl: String
|
||
createdAt: DateTime!
|
||
updatedAt: DateTime!
|
||
organization: Organization!
|
||
}
|
||
|
||
input ServiceInput {
|
||
name: String!
|
||
description: String
|
||
price: Float!
|
||
imageUrl: String
|
||
}
|
||
|
||
type ServiceResponse {
|
||
success: Boolean!
|
||
message: String!
|
||
service: Service
|
||
}
|
||
|
||
# Типы для расходников
|
||
enum SupplyType {
|
||
FULFILLMENT_CONSUMABLES # Расходники фулфилмента (купленные фулфилментом для себя)
|
||
SELLER_CONSUMABLES # Расходники селлеров (принятые от селлеров для хранения)
|
||
}
|
||
|
||
type Supply {
|
||
id: ID!
|
||
name: String!
|
||
description: String
|
||
# Новые поля для Services архитектуры
|
||
pricePerUnit: Float # Цена за единицу для рецептур (может быть null)
|
||
unit: String! # Единица измерения: "шт", "кг", "м"
|
||
warehouseStock: Int! # Остаток на складе (readonly)
|
||
isAvailable: Boolean! # Есть ли на складе (влияет на цвет)
|
||
warehouseConsumableId: ID! # Связь со складом
|
||
# Поля из базы данных для обратной совместимости
|
||
price: Float! # Цена закупки у поставщика (не меняется)
|
||
quantity: Int! # Из Prisma schema
|
||
category: String! # Из Prisma schema
|
||
status: String! # Из Prisma schema
|
||
date: DateTime! # Из Prisma schema
|
||
supplier: String! # Из Prisma schema
|
||
minStock: Int! # Из Prisma schema
|
||
currentStock: Int! # Из Prisma schema
|
||
usedStock: Int! # Из Prisma schema
|
||
type: String! # Из Prisma schema (SupplyType enum)
|
||
sellerOwnerId: ID # Из Prisma schema
|
||
sellerOwner: Organization # Из Prisma schema
|
||
shopLocation: String # Из Prisma schema
|
||
imageUrl: String
|
||
createdAt: DateTime!
|
||
updatedAt: DateTime!
|
||
organization: Organization!
|
||
}
|
||
|
||
# Для рецептур селлеров - только доступные с ценой
|
||
type SupplyForRecipe {
|
||
id: ID!
|
||
name: String!
|
||
pricePerUnit: Float! # Всегда не null
|
||
unit: String!
|
||
imageUrl: String
|
||
warehouseStock: Int! # Всегда > 0
|
||
}
|
||
|
||
# Для обновления цены расходника в разделе Услуги
|
||
input UpdateSupplyPriceInput {
|
||
pricePerUnit: Float # Может быть null (цена не установлена)
|
||
}
|
||
|
||
input UseFulfillmentSuppliesInput {
|
||
supplyId: ID!
|
||
quantityUsed: Int!
|
||
description: String # Описание использования (например, "Подготовка 300 продуктов")
|
||
}
|
||
|
||
# Устаревшие типы для обратной совместимости
|
||
input SupplyInput {
|
||
name: String!
|
||
description: String
|
||
price: Float!
|
||
imageUrl: String
|
||
}
|
||
|
||
type SupplyResponse {
|
||
success: Boolean!
|
||
message: String!
|
||
supply: Supply
|
||
}
|
||
|
||
# Типы для заказов поставок расходников
|
||
type SupplyOrder {
|
||
id: ID!
|
||
organizationId: ID!
|
||
partnerId: ID!
|
||
partner: Organization!
|
||
deliveryDate: DateTime!
|
||
status: SupplyOrderStatus!
|
||
totalAmount: Float!
|
||
totalItems: Int!
|
||
fulfillmentCenterId: ID
|
||
fulfillmentCenter: Organization
|
||
logisticsPartnerId: ID
|
||
logisticsPartner: Organization
|
||
items: [SupplyOrderItem!]!
|
||
createdAt: DateTime!
|
||
updatedAt: DateTime!
|
||
organization: Organization!
|
||
}
|
||
|
||
type SupplyOrderItem {
|
||
id: ID!
|
||
productId: ID!
|
||
product: Product!
|
||
quantity: Int!
|
||
price: Float!
|
||
totalPrice: Float!
|
||
recipe: ProductRecipe
|
||
}
|
||
|
||
enum SupplyOrderStatus {
|
||
PENDING # Ожидает одобрения поставщика
|
||
CONFIRMED # Устаревший статус (для обратной совместимости)
|
||
IN_TRANSIT # Устаревший статус (для обратной совместимости)
|
||
SUPPLIER_APPROVED # Поставщик одобрил, ожидает подтверждения логистики
|
||
LOGISTICS_CONFIRMED # Логистика подтвердила, ожидает отправки
|
||
SHIPPED # Отправлено поставщиком, в пути
|
||
DELIVERED # Доставлено и принято фулфилментом
|
||
CANCELLED # Отменено (любой участник может отменить)
|
||
}
|
||
|
||
input SupplyOrderInput {
|
||
partnerId: ID!
|
||
deliveryDate: DateTime!
|
||
fulfillmentCenterId: ID # ID фулфилмент-центра для доставки
|
||
logisticsPartnerId: ID # ID логистической компании (опционально - может выбрать селлер или фулфилмент)
|
||
items: [SupplyOrderItemInput!]!
|
||
notes: String # Дополнительные заметки к заказу
|
||
consumableType: String # Классификация расходников: FULFILLMENT_CONSUMABLES, SELLER_CONSUMABLES
|
||
}
|
||
|
||
input SupplyOrderItemInput {
|
||
productId: ID!
|
||
quantity: Int!
|
||
recipe: ProductRecipeInput
|
||
}
|
||
|
||
type PendingSuppliesCount {
|
||
supplyOrders: Int!
|
||
ourSupplyOrders: Int! # Расходники фулфилмента
|
||
sellerSupplyOrders: Int! # Расходники селлеров
|
||
incomingSupplierOrders: Int! # 🔔 Входящие заказы для поставщиков
|
||
logisticsOrders: Int! # 🚚 Логистические заявки для логистики
|
||
incomingRequests: Int!
|
||
total: Int!
|
||
}
|
||
|
||
type SupplyOrderProcessInfo {
|
||
role: String! # Роль организации в процессе (SELLER, FULFILLMENT, LOGIST)
|
||
supplier: String! # Название поставщика
|
||
fulfillmentCenter: ID # ID фулфилмент-центра
|
||
logistics: ID # ID логистической компании
|
||
status: String! # Текущий статус заказа
|
||
}
|
||
|
||
# Типы для рецептуры продуктов
|
||
type ProductRecipe {
|
||
services: [Service!]!
|
||
fulfillmentConsumables: [Supply!]!
|
||
sellerConsumables: [Supply!]!
|
||
marketplaceCardId: String
|
||
}
|
||
|
||
input ProductRecipeInput {
|
||
services: [ID!]!
|
||
fulfillmentConsumables: [ID!]!
|
||
sellerConsumables: [ID!]!
|
||
marketplaceCardId: String
|
||
}
|
||
|
||
type SupplyOrderResponse {
|
||
success: Boolean!
|
||
message: String!
|
||
order: SupplyOrder
|
||
processInfo: SupplyOrderProcessInfo # Информация о процессе поставки
|
||
}
|
||
|
||
# Типы для логистики
|
||
type Logistics {
|
||
id: ID!
|
||
fromLocation: String!
|
||
toLocation: String!
|
||
priceUnder1m3: Float!
|
||
priceOver1m3: Float!
|
||
description: String
|
||
createdAt: DateTime!
|
||
updatedAt: DateTime!
|
||
organization: Organization!
|
||
}
|
||
|
||
input LogisticsInput {
|
||
fromLocation: String!
|
||
toLocation: String!
|
||
priceUnder1m3: Float!
|
||
priceOver1m3: Float!
|
||
description: String
|
||
}
|
||
|
||
type LogisticsResponse {
|
||
success: Boolean!
|
||
message: String!
|
||
logistics: Logistics
|
||
}
|
||
|
||
# Типы для категорий товаров
|
||
type Category {
|
||
id: ID!
|
||
name: String!
|
||
createdAt: DateTime!
|
||
updatedAt: DateTime!
|
||
}
|
||
|
||
# Типы для товаров поставщика
|
||
type Product {
|
||
id: ID!
|
||
name: String!
|
||
article: String!
|
||
description: String
|
||
price: Float!
|
||
pricePerSet: Float
|
||
quantity: Int!
|
||
setQuantity: Int
|
||
ordered: Int
|
||
inTransit: Int
|
||
stock: Int
|
||
sold: Int
|
||
type: String
|
||
category: Category
|
||
brand: String
|
||
color: String
|
||
size: String
|
||
weight: Float
|
||
dimensions: String
|
||
material: String
|
||
images: [String!]!
|
||
mainImage: String
|
||
isActive: Boolean!
|
||
createdAt: DateTime!
|
||
updatedAt: DateTime!
|
||
organization: Organization!
|
||
}
|
||
|
||
input ProductInput {
|
||
name: String!
|
||
article: String!
|
||
description: String
|
||
price: Float!
|
||
pricePerSet: Float
|
||
quantity: Int!
|
||
setQuantity: Int
|
||
ordered: Int
|
||
inTransit: Int
|
||
stock: Int
|
||
sold: Int
|
||
type: String
|
||
categoryId: ID
|
||
brand: String
|
||
color: String
|
||
size: String
|
||
weight: Float
|
||
dimensions: String
|
||
material: String
|
||
images: [String!]
|
||
mainImage: String
|
||
isActive: Boolean
|
||
}
|
||
|
||
type ProductResponse {
|
||
success: Boolean!
|
||
message: String!
|
||
product: Product
|
||
}
|
||
|
||
type ArticleUniquenessResponse {
|
||
isUnique: Boolean!
|
||
existingProduct: Product
|
||
}
|
||
|
||
type ProductStockResponse {
|
||
success: Boolean!
|
||
message: String!
|
||
product: Product
|
||
}
|
||
|
||
input CategoryInput {
|
||
name: String!
|
||
}
|
||
|
||
type CategoryResponse {
|
||
success: Boolean!
|
||
message: String!
|
||
category: Category
|
||
}
|
||
|
||
# Типы для корзины
|
||
type Cart {
|
||
id: ID!
|
||
items: [CartItem!]!
|
||
totalPrice: Float!
|
||
totalItems: Int!
|
||
createdAt: DateTime!
|
||
updatedAt: DateTime!
|
||
organization: Organization!
|
||
}
|
||
|
||
type CartItem {
|
||
id: ID!
|
||
product: Product!
|
||
quantity: Int!
|
||
totalPrice: Float!
|
||
isAvailable: Boolean!
|
||
availableQuantity: Int!
|
||
createdAt: DateTime!
|
||
updatedAt: DateTime!
|
||
}
|
||
|
||
type CartResponse {
|
||
success: Boolean!
|
||
message: String!
|
||
cart: Cart
|
||
}
|
||
|
||
# Типы для избранного
|
||
type FavoritesResponse {
|
||
success: Boolean!
|
||
message: String!
|
||
favorites: [Product!]
|
||
}
|
||
|
||
# Типы для сотрудников
|
||
type Employee {
|
||
id: ID!
|
||
firstName: String!
|
||
lastName: String!
|
||
middleName: String
|
||
fullName: String
|
||
name: String
|
||
birthDate: DateTime
|
||
avatar: String
|
||
passportPhoto: String
|
||
passportSeries: String
|
||
passportNumber: String
|
||
passportIssued: String
|
||
passportDate: DateTime
|
||
address: String
|
||
position: String!
|
||
department: String
|
||
hireDate: DateTime!
|
||
salary: Float
|
||
status: EmployeeStatus!
|
||
phone: String!
|
||
email: String
|
||
telegram: String
|
||
whatsapp: String
|
||
emergencyContact: String
|
||
emergencyPhone: String
|
||
scheduleRecords: [EmployeeSchedule!]!
|
||
organization: Organization!
|
||
createdAt: DateTime!
|
||
updatedAt: DateTime!
|
||
}
|
||
|
||
enum EmployeeStatus {
|
||
ACTIVE
|
||
VACATION
|
||
SICK
|
||
FIRED
|
||
}
|
||
|
||
type EmployeeSchedule {
|
||
id: ID!
|
||
date: DateTime!
|
||
status: ScheduleStatus!
|
||
hoursWorked: Float
|
||
overtimeHours: Float
|
||
notes: String
|
||
employee: Employee!
|
||
createdAt: DateTime!
|
||
updatedAt: DateTime!
|
||
}
|
||
|
||
enum ScheduleStatus {
|
||
WORK
|
||
WEEKEND
|
||
VACATION
|
||
SICK
|
||
ABSENT
|
||
}
|
||
|
||
input CreateEmployeeInput {
|
||
firstName: String!
|
||
lastName: String!
|
||
middleName: String
|
||
birthDate: DateTime
|
||
avatar: String
|
||
passportPhoto: String
|
||
passportSeries: String
|
||
passportNumber: String
|
||
passportIssued: String
|
||
passportDate: DateTime
|
||
address: String
|
||
position: String!
|
||
department: String
|
||
hireDate: DateTime!
|
||
salary: Float
|
||
phone: String!
|
||
email: String
|
||
telegram: String
|
||
whatsapp: String
|
||
emergencyContact: String
|
||
emergencyPhone: String
|
||
}
|
||
|
||
input UpdateEmployeeInput {
|
||
firstName: String
|
||
lastName: String
|
||
middleName: String
|
||
birthDate: DateTime
|
||
avatar: String
|
||
passportPhoto: String
|
||
passportSeries: String
|
||
passportNumber: String
|
||
passportIssued: String
|
||
passportDate: DateTime
|
||
address: String
|
||
position: String
|
||
department: String
|
||
hireDate: DateTime
|
||
salary: Float
|
||
status: EmployeeStatus
|
||
phone: String
|
||
email: String
|
||
telegram: String
|
||
whatsapp: String
|
||
emergencyContact: String
|
||
emergencyPhone: String
|
||
}
|
||
|
||
input UpdateScheduleInput {
|
||
employeeId: ID!
|
||
date: DateTime!
|
||
status: ScheduleStatus!
|
||
hoursWorked: Float
|
||
overtimeHours: Float
|
||
notes: String
|
||
}
|
||
|
||
type EmployeeResponse {
|
||
success: Boolean!
|
||
message: String!
|
||
employee: Employee
|
||
}
|
||
|
||
type EmployeesResponse {
|
||
success: Boolean!
|
||
message: String!
|
||
employees: [Employee!]!
|
||
}
|
||
|
||
# JSON скаляр
|
||
scalar JSON
|
||
|
||
# Админ типы
|
||
type Admin {
|
||
id: ID!
|
||
username: String!
|
||
email: String
|
||
isActive: Boolean!
|
||
lastLogin: String
|
||
createdAt: DateTime!
|
||
updatedAt: DateTime!
|
||
}
|
||
|
||
type AdminAuthResponse {
|
||
success: Boolean!
|
||
message: String!
|
||
token: String
|
||
admin: Admin
|
||
}
|
||
|
||
type UsersResponse {
|
||
users: [User!]!
|
||
total: Int!
|
||
hasMore: Boolean!
|
||
}
|
||
|
||
# Типы для поставок Wildberries
|
||
type WildberriesSupply {
|
||
id: ID!
|
||
deliveryDate: DateTime
|
||
status: WildberriesSupplyStatus!
|
||
totalAmount: Float!
|
||
totalItems: Int!
|
||
cards: [WildberriesSupplyCard!]!
|
||
organization: Organization!
|
||
createdAt: DateTime!
|
||
updatedAt: DateTime!
|
||
}
|
||
|
||
type WildberriesSupplyCard {
|
||
id: ID!
|
||
nmId: String!
|
||
vendorCode: String!
|
||
title: String!
|
||
brand: String
|
||
price: Float!
|
||
discountedPrice: Float
|
||
quantity: Int!
|
||
selectedQuantity: Int!
|
||
selectedMarket: String
|
||
selectedPlace: String
|
||
sellerName: String
|
||
sellerPhone: String
|
||
deliveryDate: DateTime
|
||
mediaFiles: [String!]!
|
||
selectedServices: [String!]!
|
||
createdAt: DateTime!
|
||
updatedAt: DateTime!
|
||
}
|
||
|
||
enum WildberriesSupplyStatus {
|
||
DRAFT
|
||
CREATED
|
||
IN_PROGRESS
|
||
DELIVERED
|
||
CANCELLED
|
||
}
|
||
|
||
input CreateWildberriesSupplyInput {
|
||
deliveryDate: DateTime
|
||
cards: [WildberriesSupplyCardInput!]!
|
||
}
|
||
|
||
input WildberriesSupplyCardInput {
|
||
nmId: String!
|
||
vendorCode: String!
|
||
title: String!
|
||
brand: String
|
||
price: Float!
|
||
discountedPrice: Float
|
||
quantity: Int!
|
||
selectedQuantity: Int!
|
||
selectedMarket: String
|
||
selectedPlace: String
|
||
sellerName: String
|
||
sellerPhone: String
|
||
deliveryDate: DateTime
|
||
mediaFiles: [String!]
|
||
selectedServices: [String!]
|
||
}
|
||
|
||
input UpdateWildberriesSupplyInput {
|
||
deliveryDate: DateTime
|
||
status: WildberriesSupplyStatus
|
||
cards: [WildberriesSupplyCardInput!]
|
||
}
|
||
|
||
type WildberriesSupplyResponse {
|
||
success: Boolean!
|
||
message: String!
|
||
supply: WildberriesSupply
|
||
}
|
||
|
||
# Wildberries статистика
|
||
type WildberriesStatistics {
|
||
date: String!
|
||
sales: Int!
|
||
orders: Int!
|
||
advertising: Float!
|
||
refusals: Int!
|
||
returns: Int!
|
||
revenue: Float!
|
||
buyoutPercentage: Float!
|
||
}
|
||
|
||
type WildberriesStatisticsResponse {
|
||
success: Boolean!
|
||
message: String
|
||
data: [WildberriesStatistics!]!
|
||
}
|
||
|
||
type DebugAdvertsResponse {
|
||
success: Boolean!
|
||
message: String
|
||
campaignsCount: Int!
|
||
campaigns: [DebugCampaign!]
|
||
}
|
||
|
||
type DebugCampaign {
|
||
id: Int!
|
||
name: String!
|
||
status: Int!
|
||
type: Int!
|
||
}
|
||
|
||
# Типы для поставщиков поставок
|
||
type SupplySupplier {
|
||
id: ID!
|
||
name: String!
|
||
contactName: String!
|
||
phone: String!
|
||
market: String
|
||
address: String
|
||
place: String
|
||
telegram: String
|
||
createdAt: DateTime!
|
||
}
|
||
|
||
input CreateSupplySupplierInput {
|
||
name: String!
|
||
contactName: String!
|
||
phone: String!
|
||
market: String
|
||
address: String
|
||
place: String
|
||
telegram: String
|
||
}
|
||
|
||
type SupplySupplierResponse {
|
||
success: Boolean!
|
||
message: String
|
||
supplier: SupplySupplier
|
||
}
|
||
|
||
# Типы для статистики кампаний
|
||
input WildberriesCampaignStatsInput {
|
||
campaigns: [CampaignStatsRequest!]!
|
||
}
|
||
|
||
input CampaignStatsRequest {
|
||
id: Int!
|
||
dates: [String!]
|
||
interval: CampaignStatsInterval
|
||
}
|
||
|
||
input CampaignStatsInterval {
|
||
begin: String!
|
||
end: String!
|
||
}
|
||
|
||
type WildberriesCampaignStatsResponse {
|
||
success: Boolean!
|
||
message: String
|
||
data: [WildberriesCampaignStats!]!
|
||
}
|
||
|
||
type WildberriesCampaignStats {
|
||
advertId: Int!
|
||
views: Int!
|
||
clicks: Int!
|
||
ctr: Float!
|
||
cpc: Float!
|
||
sum: Float!
|
||
atbs: Int!
|
||
orders: Int!
|
||
cr: Float!
|
||
shks: Int!
|
||
sum_price: Float!
|
||
interval: WildberriesCampaignInterval
|
||
days: [WildberriesCampaignDayStats!]!
|
||
boosterStats: [WildberriesBoosterStats!]!
|
||
}
|
||
|
||
type WildberriesCampaignInterval {
|
||
begin: String!
|
||
end: String!
|
||
}
|
||
|
||
type WildberriesCampaignDayStats {
|
||
date: String!
|
||
views: Int!
|
||
clicks: Int!
|
||
ctr: Float!
|
||
cpc: Float!
|
||
sum: Float!
|
||
atbs: Int!
|
||
orders: Int!
|
||
cr: Float!
|
||
shks: Int!
|
||
sum_price: Float!
|
||
apps: [WildberriesAppStats!]
|
||
}
|
||
|
||
type WildberriesAppStats {
|
||
views: Int!
|
||
clicks: Int!
|
||
ctr: Float!
|
||
cpc: Float!
|
||
sum: Float!
|
||
atbs: Int!
|
||
orders: Int!
|
||
cr: Float!
|
||
shks: Int!
|
||
sum_price: Float!
|
||
appType: Int!
|
||
nm: [WildberriesProductStats!]
|
||
}
|
||
|
||
type WildberriesProductStats {
|
||
views: Int!
|
||
clicks: Int!
|
||
ctr: Float!
|
||
cpc: Float!
|
||
sum: Float!
|
||
atbs: Int!
|
||
orders: Int!
|
||
cr: Float!
|
||
shks: Int!
|
||
sum_price: Float!
|
||
name: String!
|
||
nmId: Int!
|
||
}
|
||
|
||
type WildberriesBoosterStats {
|
||
date: String!
|
||
nm: Int!
|
||
avg_position: Float!
|
||
}
|
||
|
||
# Типы для списка кампаний
|
||
type WildberriesCampaignsListResponse {
|
||
success: Boolean!
|
||
message: String
|
||
data: WildberriesCampaignsData!
|
||
}
|
||
|
||
type WildberriesCampaignsData {
|
||
adverts: [WildberriesCampaignGroup!]!
|
||
all: Int!
|
||
}
|
||
|
||
type WildberriesCampaignGroup {
|
||
type: Int!
|
||
status: Int!
|
||
count: Int!
|
||
advert_list: [WildberriesCampaignItem!]!
|
||
}
|
||
|
||
type WildberriesCampaignItem {
|
||
advertId: Int!
|
||
changeTime: String!
|
||
}
|
||
|
||
# Типы для внешней рекламы
|
||
type ExternalAd {
|
||
id: ID!
|
||
name: String!
|
||
url: String!
|
||
cost: Float!
|
||
date: String!
|
||
nmId: String!
|
||
clicks: Int!
|
||
organizationId: String!
|
||
createdAt: String!
|
||
updatedAt: String!
|
||
}
|
||
|
||
input ExternalAdInput {
|
||
name: String!
|
||
url: String!
|
||
cost: Float!
|
||
date: String!
|
||
nmId: String!
|
||
}
|
||
|
||
type ExternalAdResponse {
|
||
success: Boolean!
|
||
message: String
|
||
externalAd: ExternalAd
|
||
}
|
||
|
||
type ExternalAdsResponse {
|
||
success: Boolean!
|
||
message: String
|
||
externalAds: [ExternalAd!]!
|
||
}
|
||
|
||
extend type Query {
|
||
getExternalAds(dateFrom: String!, dateTo: String!): ExternalAdsResponse!
|
||
}
|
||
|
||
extend type Mutation {
|
||
createExternalAd(input: ExternalAdInput!): ExternalAdResponse!
|
||
updateExternalAd(id: ID!, input: ExternalAdInput!): ExternalAdResponse!
|
||
deleteExternalAd(id: ID!): ExternalAdResponse!
|
||
updateExternalAdClicks(id: ID!, clicks: Int!): ExternalAdResponse!
|
||
}
|
||
|
||
# Типы для кеша склада WB
|
||
type WBWarehouseCache {
|
||
id: ID!
|
||
organizationId: String!
|
||
cacheDate: String!
|
||
data: String! # JSON строка с данными
|
||
totalProducts: Int!
|
||
totalStocks: Int!
|
||
totalReserved: Int!
|
||
createdAt: String!
|
||
updatedAt: String!
|
||
}
|
||
|
||
type WBWarehouseCacheResponse {
|
||
success: Boolean!
|
||
message: String
|
||
cache: WBWarehouseCache
|
||
fromCache: Boolean! # Указывает, получены ли данные из кеша
|
||
}
|
||
|
||
input WBWarehouseCacheInput {
|
||
data: String! # JSON строка с данными склада
|
||
totalProducts: Int!
|
||
totalStocks: Int!
|
||
totalReserved: Int!
|
||
}
|
||
|
||
extend type Query {
|
||
getWBWarehouseData: WBWarehouseCacheResponse!
|
||
}
|
||
|
||
extend type Mutation {
|
||
saveWBWarehouseCache(input: WBWarehouseCacheInput!): WBWarehouseCacheResponse!
|
||
}
|
||
|
||
# Типы для заявок на возврат WB
|
||
type WbReturnClaim {
|
||
id: String!
|
||
claimType: Int!
|
||
status: Int!
|
||
statusEx: Int!
|
||
nmId: Int!
|
||
userComment: String!
|
||
wbComment: String
|
||
dt: String!
|
||
imtName: String!
|
||
orderDt: String!
|
||
dtUpdate: String!
|
||
photos: [String!]!
|
||
videoPaths: [String!]!
|
||
actions: [String!]!
|
||
price: Int!
|
||
currencyCode: String!
|
||
srid: String!
|
||
sellerOrganization: WbSellerOrganization!
|
||
}
|
||
|
||
type WbSellerOrganization {
|
||
id: String!
|
||
name: String!
|
||
inn: String!
|
||
}
|
||
|
||
type WbReturnClaimsResponse {
|
||
claims: [WbReturnClaim!]!
|
||
total: Int!
|
||
}
|
||
|
||
# Типы для статистики склада фулфилмента
|
||
type FulfillmentWarehouseStats {
|
||
products: WarehouseStatsItem!
|
||
goods: WarehouseStatsItem!
|
||
defects: WarehouseStatsItem!
|
||
pvzReturns: WarehouseStatsItem!
|
||
fulfillmentSupplies: WarehouseStatsItem!
|
||
sellerSupplies: WarehouseStatsItem!
|
||
}
|
||
|
||
type WarehouseStatsItem {
|
||
current: Int!
|
||
change: Int!
|
||
percentChange: Float!
|
||
}
|
||
|
||
extend type Query {
|
||
fulfillmentWarehouseStats: FulfillmentWarehouseStats!
|
||
}
|
||
`
|