[598][@ant] feat: реестр всех предложений кооператива на столе администратора (Offer:read:all)
Новая страница «Реестр предложений» (market-admin) — все предложения всех поставщиков любого статуса (опубликованные/снятые/отклонённые/на модерации), отдельно от «Модерации» (там только ждущие решения). Клик по строке → readonly- карточка предложения (marketplace-admin-offer-detail) — туда же ведёт переход «Открыть предложение» из реестра заказов. - backend: marketplaceListAllOffers (Offer:read:all) + offerService.listAll; read:all добавлен админу в access-matrix (у совета уже был); - DRY: логика username→ФИО вынесена из реестра процессов в общий composable useFioCache, переиспользована в реестре предложений. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+3
-1
@@ -95,7 +95,9 @@ export const marketplaceAccessMatrix: Record<MarketplaceRole, Record<string, str
|
||||
Economy: ['read', 'read:own-KU', 'configure:own-KU', 'use:own'],
|
||||
},
|
||||
admin: {
|
||||
Offer: ['moderate', 'read'],
|
||||
// read:all — реестр всех предложений кооператива любого статуса (наряду с
|
||||
// модерацией PENDING); read:all есть и у совета (board_readonly).
|
||||
Offer: ['moderate', 'read', 'read:all'],
|
||||
Order: ['read:all'],
|
||||
KU: ['manage'],
|
||||
Whitelist: ['manage'],
|
||||
|
||||
+15
-1
@@ -18,7 +18,7 @@ import {
|
||||
} from 'class-validator';
|
||||
import { PaginationInputDTO } from '~/application/common/dto/pagination.dto';
|
||||
import { MARKETPLACE_OFFER_MAX_IMAGES } from '../../domain/entities/marketplace-offer.types';
|
||||
import { MarketplaceBarcodeStrategyEnum } from './marketplace-offer.dto';
|
||||
import { MarketplaceBarcodeStrategyEnum, MarketplaceOfferStatusEnum } from './marketplace-offer.dto';
|
||||
|
||||
const UNITS = ['piece', 'kg', 'liter', 'pack'] as const;
|
||||
|
||||
@@ -249,3 +249,17 @@ export class MarketplaceRepublishOfferInputDTO {
|
||||
|
||||
@InputType('MarketplaceListMyOffersInput')
|
||||
export class MarketplaceListMyOffersInputDTO extends PaginationInputDTO {}
|
||||
|
||||
@InputType('MarketplaceListAllOffersInput', {
|
||||
description: 'Параметры фильтрации реестра всех предложений кооператива (стол администратора).',
|
||||
})
|
||||
export class MarketplaceListAllOffersInputDTO extends PaginationInputDTO {
|
||||
@Field(() => [MarketplaceOfferStatusEnum], {
|
||||
nullable: true,
|
||||
description: 'Один или несколько статусов предложения, по которым нужно отфильтровать список.',
|
||||
})
|
||||
public readonly statuses?: MarketplaceOfferStatusEnum[];
|
||||
|
||||
@Field(() => String, { nullable: true, description: 'Фильтр по аккаунту поставщика.' })
|
||||
public readonly supplier_account?: string;
|
||||
}
|
||||
|
||||
+35
@@ -14,6 +14,7 @@ import {
|
||||
} from '../dto/marketplace-offer.dto';
|
||||
import {
|
||||
MarketplaceCreateOfferInputDTO,
|
||||
MarketplaceListAllOffersInputDTO,
|
||||
MarketplaceListMyOffersInputDTO,
|
||||
MarketplaceRepublishOfferInputDTO,
|
||||
MarketplaceUpdateOfferInputDTO,
|
||||
@@ -35,6 +36,7 @@ import {
|
||||
type AvailableCategoryDomainService,
|
||||
} from '../../domain/services/available-category-domain.service';
|
||||
import type { MarketplaceOfferDomainEntity } from '../../domain/entities/marketplace-offer.entity';
|
||||
import type { MarketplaceOfferStatus } from '../../domain/entities/marketplace-offer.types';
|
||||
|
||||
const toDTO = toMarketplaceOfferDTO;
|
||||
|
||||
@@ -216,4 +218,37 @@ export class MarketplaceOfferResolver {
|
||||
currentPage: result.currentPage,
|
||||
};
|
||||
}
|
||||
|
||||
@Query(() => MarketplaceOfferPaginationResultDTO, {
|
||||
name: 'marketplaceListAllOffers',
|
||||
description: 'Реестр всех предложений кооператива любого статуса (стол администратора).',
|
||||
})
|
||||
@UseGuards(GqlJwtAuthGuard, MarketplaceMembershipGuard, MarketplaceRoleGuard)
|
||||
@RequireMarketplaceAccess('Offer', 'read:all')
|
||||
async marketplaceListAllOffers(
|
||||
@Args('input', { nullable: true }) input?: MarketplaceListAllOffersInputDTO
|
||||
): Promise<MarketplaceOfferPaginationResultDTO> {
|
||||
const pagination = {
|
||||
page: input?.page ?? 1,
|
||||
limit: input?.limit ?? 50,
|
||||
sortBy: input?.sortBy ?? 'created_at',
|
||||
sortOrder: (input?.sortOrder ?? 'DESC') as 'ASC' | 'DESC',
|
||||
};
|
||||
const result = await this.offerService.listAll(
|
||||
config.coopname,
|
||||
{
|
||||
statuses: input?.statuses?.length
|
||||
? (input.statuses as unknown as MarketplaceOfferStatus[])
|
||||
: undefined,
|
||||
supplier_account: input?.supplier_account,
|
||||
},
|
||||
pagination
|
||||
);
|
||||
return {
|
||||
items: result.items.map(toDTO),
|
||||
totalCount: result.totalCount,
|
||||
totalPages: result.totalPages,
|
||||
currentPage: result.currentPage,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
+17
@@ -400,6 +400,23 @@ export class MarketplaceOfferService {
|
||||
return this.repo.list({ coopname, supplier_account }, pagination);
|
||||
}
|
||||
|
||||
// Реестр всех предложений кооператива (стол администратора): любой статус
|
||||
// и любой поставщик, с опциональными фильтрами по статусу и поставщику.
|
||||
async listAll(
|
||||
coopname: string,
|
||||
filter: { statuses?: MarketplaceOfferStatus[]; supplier_account?: string },
|
||||
pagination: PaginationInputDomainInterface
|
||||
): Promise<PaginationResultDomainInterface<MarketplaceOfferDomainEntity>> {
|
||||
return this.repo.list(
|
||||
{
|
||||
coopname,
|
||||
...(filter.supplier_account ? { supplier_account: filter.supplier_account } : {}),
|
||||
...(filter.statuses?.length ? { status: filter.statuses } : {}),
|
||||
},
|
||||
pagination
|
||||
);
|
||||
}
|
||||
|
||||
async getById(id: string): Promise<MarketplaceOfferDomainEntity | null> {
|
||||
return this.repo.findById(id);
|
||||
}
|
||||
|
||||
@@ -795,6 +795,9 @@ export const AllTypesProps: Record<string,any> = {
|
||||
MarketplaceKUStatus: "enum" as const,
|
||||
MarketplaceListAidsInput:{
|
||||
|
||||
},
|
||||
MarketplaceListAllOffersInput:{
|
||||
statuses:"MarketplaceOfferStatus"
|
||||
},
|
||||
MarketplaceListAplReceptionsByBranameInput:{
|
||||
|
||||
@@ -2163,6 +2166,9 @@ export const AllTypesProps: Record<string,any> = {
|
||||
marketplaceListAids:{
|
||||
data:"MarketplaceListAidsInput"
|
||||
},
|
||||
marketplaceListAllOffers:{
|
||||
input:"MarketplaceListAllOffersInput"
|
||||
},
|
||||
marketplaceListAllOrders:{
|
||||
input:"MarketplaceListOrdersInput",
|
||||
options:"PaginationInput"
|
||||
@@ -5850,6 +5856,7 @@ export const ReturnTypes: Record<string,any> = {
|
||||
marketplaceIssueActChairmanSignablePayload:"GeneratedDocument",
|
||||
marketplaceIssueActOrdererSignablePayload:"DocumentAggregate",
|
||||
marketplaceListAids:"MarketplaceAid",
|
||||
marketplaceListAllOffers:"MarketplaceOfferPaginationResult",
|
||||
marketplaceListAllOrders:"MarketplaceOrderPaginationResult",
|
||||
marketplaceListAplReceptionsAsSupplier:"MarketplaceAplReception",
|
||||
marketplaceListAplReceptionsByBraname:"MarketplaceAplReception",
|
||||
|
||||
@@ -7193,6 +7193,21 @@ export type ValueTypes = {
|
||||
["MarketplaceListAidsInput"]: {
|
||||
/** Показать заявки только этого получателя (по умолчанию — свои). */
|
||||
username?: string | undefined | null | Variable<any, string>
|
||||
};
|
||||
/** Параметры фильтрации реестра всех предложений кооператива (стол администратора). */
|
||||
["MarketplaceListAllOffersInput"]: {
|
||||
/** Количество элементов на странице */
|
||||
limit: number | Variable<any, string>,
|
||||
/** Номер страницы */
|
||||
page: number | Variable<any, string>,
|
||||
/** Ключ сортировки (например, "name") */
|
||||
sortBy?: string | undefined | null | Variable<any, string>,
|
||||
/** Направление сортировки ("ASC" или "DESC") */
|
||||
sortOrder: string | Variable<any, string>,
|
||||
/** Один или несколько статусов предложения, по которым нужно отфильтровать список. */
|
||||
statuses?: Array<ValueTypes["MarketplaceOfferStatus"]> | undefined | null | Variable<any, string>,
|
||||
/** Фильтр по аккаунту поставщика. */
|
||||
supplier_account?: string | undefined | null | Variable<any, string>
|
||||
};
|
||||
["MarketplaceListAplReceptionsByBranameInput"]: {
|
||||
/** Идентификатор КУ-получателя. */
|
||||
@@ -10369,6 +10384,7 @@ marketplaceGetUserRequests?: [{ data?: ValueTypes["GetUserRequestsInput"] | unde
|
||||
marketplaceIssueActChairmanSignablePayload?: [{ data: ValueTypes["MarketplaceIssueActPayloadInput"] | Variable<any, string>},ValueTypes["GeneratedDocument"]],
|
||||
marketplaceIssueActOrdererSignablePayload?: [{ data: ValueTypes["MarketplaceIssueActPayloadInput"] | Variable<any, string>},ValueTypes["DocumentAggregate"]],
|
||||
marketplaceListAids?: [{ data?: ValueTypes["MarketplaceListAidsInput"] | undefined | null | Variable<any, string>},ValueTypes["MarketplaceAid"]],
|
||||
marketplaceListAllOffers?: [{ input?: ValueTypes["MarketplaceListAllOffersInput"] | undefined | null | Variable<any, string>},ValueTypes["MarketplaceOfferPaginationResult"]],
|
||||
marketplaceListAllOrders?: [{ input?: ValueTypes["MarketplaceListOrdersInput"] | undefined | null | Variable<any, string>, options?: ValueTypes["PaginationInput"] | undefined | null | Variable<any, string>},ValueTypes["MarketplaceOrderPaginationResult"]],
|
||||
/** Список актов приёмки, ожидающих подписи текущего поставщика. */
|
||||
marketplaceListAplReceptionsAsSupplier?:ValueTypes["MarketplaceAplReception"],
|
||||
@@ -17953,6 +17969,21 @@ export type ResolverInputTypes = {
|
||||
["MarketplaceListAidsInput"]: {
|
||||
/** Показать заявки только этого получателя (по умолчанию — свои). */
|
||||
username?: string | undefined | null
|
||||
};
|
||||
/** Параметры фильтрации реестра всех предложений кооператива (стол администратора). */
|
||||
["MarketplaceListAllOffersInput"]: {
|
||||
/** Количество элементов на странице */
|
||||
limit: number,
|
||||
/** Номер страницы */
|
||||
page: number,
|
||||
/** Ключ сортировки (например, "name") */
|
||||
sortBy?: string | undefined | null,
|
||||
/** Направление сортировки ("ASC" или "DESC") */
|
||||
sortOrder: string,
|
||||
/** Один или несколько статусов предложения, по которым нужно отфильтровать список. */
|
||||
statuses?: Array<ResolverInputTypes["MarketplaceOfferStatus"]> | undefined | null,
|
||||
/** Фильтр по аккаунту поставщика. */
|
||||
supplier_account?: string | undefined | null
|
||||
};
|
||||
["MarketplaceListAplReceptionsByBranameInput"]: {
|
||||
/** Идентификатор КУ-получателя. */
|
||||
@@ -21011,6 +21042,7 @@ marketplaceGetUserRequests?: [{ data?: ResolverInputTypes["GetUserRequestsInput"
|
||||
marketplaceIssueActChairmanSignablePayload?: [{ data: ResolverInputTypes["MarketplaceIssueActPayloadInput"]},ResolverInputTypes["GeneratedDocument"]],
|
||||
marketplaceIssueActOrdererSignablePayload?: [{ data: ResolverInputTypes["MarketplaceIssueActPayloadInput"]},ResolverInputTypes["DocumentAggregate"]],
|
||||
marketplaceListAids?: [{ data?: ResolverInputTypes["MarketplaceListAidsInput"] | undefined | null},ResolverInputTypes["MarketplaceAid"]],
|
||||
marketplaceListAllOffers?: [{ input?: ResolverInputTypes["MarketplaceListAllOffersInput"] | undefined | null},ResolverInputTypes["MarketplaceOfferPaginationResult"]],
|
||||
marketplaceListAllOrders?: [{ input?: ResolverInputTypes["MarketplaceListOrdersInput"] | undefined | null, options?: ResolverInputTypes["PaginationInput"] | undefined | null},ResolverInputTypes["MarketplaceOrderPaginationResult"]],
|
||||
/** Список актов приёмки, ожидающих подписи текущего поставщика. */
|
||||
marketplaceListAplReceptionsAsSupplier?:ResolverInputTypes["MarketplaceAplReception"],
|
||||
@@ -28341,6 +28373,21 @@ export type ModelTypes = {
|
||||
["MarketplaceListAidsInput"]: {
|
||||
/** Показать заявки только этого получателя (по умолчанию — свои). */
|
||||
username?: string | undefined | null
|
||||
};
|
||||
/** Параметры фильтрации реестра всех предложений кооператива (стол администратора). */
|
||||
["MarketplaceListAllOffersInput"]: {
|
||||
/** Количество элементов на странице */
|
||||
limit: number,
|
||||
/** Номер страницы */
|
||||
page: number,
|
||||
/** Ключ сортировки (например, "name") */
|
||||
sortBy?: string | undefined | null,
|
||||
/** Направление сортировки ("ASC" или "DESC") */
|
||||
sortOrder: string,
|
||||
/** Один или несколько статусов предложения, по которым нужно отфильтровать список. */
|
||||
statuses?: Array<ModelTypes["MarketplaceOfferStatus"]> | undefined | null,
|
||||
/** Фильтр по аккаунту поставщика. */
|
||||
supplier_account?: string | undefined | null
|
||||
};
|
||||
["MarketplaceListAplReceptionsByBranameInput"]: {
|
||||
/** Идентификатор КУ-получателя. */
|
||||
@@ -32016,6 +32063,8 @@ export type ModelTypes = {
|
||||
marketplaceIssueActOrdererSignablePayload: ModelTypes["DocumentAggregate"],
|
||||
/** Заявки на материальную помощь: свои — для доверенного; все заявки кооператива — для администратора. */
|
||||
marketplaceListAids: Array<ModelTypes["MarketplaceAid"]>,
|
||||
/** Реестр всех предложений кооператива любого статуса (стол администратора). */
|
||||
marketplaceListAllOffers: ModelTypes["MarketplaceOfferPaginationResult"],
|
||||
/** Реестр всех заказов кооператива с их текущими статусами (стол администратора). */
|
||||
marketplaceListAllOrders: ModelTypes["MarketplaceOrderPaginationResult"],
|
||||
/** Список актов приёмки, ожидающих подписи текущего поставщика. */
|
||||
@@ -39708,6 +39757,21 @@ export type GraphQLTypes = {
|
||||
["MarketplaceListAidsInput"]: {
|
||||
/** Показать заявки только этого получателя (по умолчанию — свои). */
|
||||
username?: string | undefined | null
|
||||
};
|
||||
/** Параметры фильтрации реестра всех предложений кооператива (стол администратора). */
|
||||
["MarketplaceListAllOffersInput"]: {
|
||||
/** Количество элементов на странице */
|
||||
limit: number,
|
||||
/** Номер страницы */
|
||||
page: number,
|
||||
/** Ключ сортировки (например, "name") */
|
||||
sortBy?: string | undefined | null,
|
||||
/** Направление сортировки ("ASC" или "DESC") */
|
||||
sortOrder: string,
|
||||
/** Один или несколько статусов предложения, по которым нужно отфильтровать список. */
|
||||
statuses?: Array<GraphQLTypes["MarketplaceOfferStatus"]> | undefined | null,
|
||||
/** Фильтр по аккаунту поставщика. */
|
||||
supplier_account?: string | undefined | null
|
||||
};
|
||||
["MarketplaceListAplReceptionsByBranameInput"]: {
|
||||
/** Идентификатор КУ-получателя. */
|
||||
@@ -43653,6 +43717,8 @@ export type GraphQLTypes = {
|
||||
marketplaceIssueActOrdererSignablePayload: GraphQLTypes["DocumentAggregate"],
|
||||
/** Заявки на материальную помощь: свои — для доверенного; все заявки кооператива — для администратора. */
|
||||
marketplaceListAids: Array<GraphQLTypes["MarketplaceAid"]>,
|
||||
/** Реестр всех предложений кооператива любого статуса (стол администратора). */
|
||||
marketplaceListAllOffers: GraphQLTypes["MarketplaceOfferPaginationResult"],
|
||||
/** Реестр всех заказов кооператива с их текущими статусами (стол администратора). */
|
||||
marketplaceListAllOrders: GraphQLTypes["MarketplaceOrderPaginationResult"],
|
||||
/** Список актов приёмки, ожидающих подписи текущего поставщика. */
|
||||
@@ -46240,6 +46306,7 @@ type ZEUS_VARIABLES = {
|
||||
["MarketplaceIssueActSignedMetaDocumentInput"]: ValueTypes["MarketplaceIssueActSignedMetaDocumentInput"];
|
||||
["MarketplaceKUStatus"]: ValueTypes["MarketplaceKUStatus"];
|
||||
["MarketplaceListAidsInput"]: ValueTypes["MarketplaceListAidsInput"];
|
||||
["MarketplaceListAllOffersInput"]: ValueTypes["MarketplaceListAllOffersInput"];
|
||||
["MarketplaceListAplReceptionsByBranameInput"]: ValueTypes["MarketplaceListAplReceptionsByBranameInput"];
|
||||
["MarketplaceListCatalogInput"]: ValueTypes["MarketplaceListCatalogInput"];
|
||||
["MarketplaceListConsolidatedRequestsInput"]: ValueTypes["MarketplaceListConsolidatedRequestsInput"];
|
||||
|
||||
@@ -22,6 +22,7 @@ import { OffererPaymentHistoryPage } from 'src/pages/Marketplace/OffererPaymentH
|
||||
import { AdminWriteoffsPage } from 'src/pages/Marketplace/AdminWriteoffs'
|
||||
import { ChairmanModerationPage } from 'src/pages/Marketplace/ChairmanModeration'
|
||||
import { AdminOrdersPage } from 'src/pages/Marketplace/AdminOrders'
|
||||
import { AdminOffersPage } from 'src/pages/Marketplace/AdminOffers'
|
||||
import { AdminIssuancePointsPage } from 'src/pages/Marketplace/AdminIssuancePoints'
|
||||
import { OperatorOwnWarehousePage } from 'src/pages/Marketplace/OperatorOwnWarehouse'
|
||||
import { AdminWarehouseSummaryPage } from 'src/pages/Marketplace/AdminWarehouseSummary'
|
||||
@@ -637,6 +638,24 @@ export default async function (): Promise<IWorkspaceConfig[]> {
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
// Реестр всех предложений кооператива любого статуса
|
||||
// (опубликованные/снятые/отклонённые/на модерации), всех
|
||||
// поставщиков (`Offer:read:all` — у admin и board_readonly).
|
||||
// Отдельно от «Модерации» (там только ждущие решения); на эти
|
||||
// карточки ведёт переход «Открыть предложение» из реестра заказов.
|
||||
path: 'offers',
|
||||
name: 'marketplace-admin-offers',
|
||||
component: markRaw(AdminOffersPage),
|
||||
meta: {
|
||||
title: 'Реестр предложений',
|
||||
icon: 'storefront',
|
||||
requires: 'Offer:read:all',
|
||||
requiresAuth: true,
|
||||
agreements: agreementsBase,
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
// Эпик 3 / Story 3.6: admin-стол модерации offer'ов. Виден совету
|
||||
// и председателю (`Order:read:all` есть у board_readonly и admin).
|
||||
|
||||
@@ -143,7 +143,7 @@ import { ExpandToggleButton } from 'src/shared/ui/ExpandToggleButton'
|
||||
import { EntityIdBadge } from 'src/shared/ui'
|
||||
import { copyToClipboard } from 'quasar'
|
||||
import { useProcessStore, type IProcessSummary } from 'src/entities/Process'
|
||||
import { useAccountStore } from 'src/entities/Account'
|
||||
import { useFioCache } from 'src/shared/lib/account/useFioCache'
|
||||
import { ProcessDetailCard } from 'src/widgets/Process/ProcessDetailCard'
|
||||
import {
|
||||
processChipBg,
|
||||
@@ -157,12 +157,11 @@ const { isMobile } = useWindowSize()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const processStore = useProcessStore()
|
||||
const accountStore = useAccountStore()
|
||||
const { fioCache, enrichFio } = useFioCache()
|
||||
|
||||
const loading = ref(false)
|
||||
const items = ref<IProcessSummary[]>([])
|
||||
const expanded = ref(new Map<string, boolean>())
|
||||
const fioCache = ref(new Map<string, string>())
|
||||
|
||||
const pagination = ref({ page: 1, rowsPerPage: 50, rowsNumber: 0 })
|
||||
|
||||
@@ -333,35 +332,6 @@ function toggleExpand(processHash: string) {
|
||||
expanded.value.set(processHash, !expanded.value.get(processHash))
|
||||
}
|
||||
|
||||
async function enrichFio(rawUsernames: (string | null | undefined)[]) {
|
||||
const usernames = [
|
||||
...new Set(rawUsernames.filter((u): u is string => !!u && !fioCache.value.has(u))),
|
||||
]
|
||||
if (!usernames.length) return
|
||||
await Promise.allSettled(
|
||||
usernames.map(async (username) => {
|
||||
try {
|
||||
const acc = await accountStore.getAccount(username)
|
||||
const pd = acc?.private_account
|
||||
if (!pd) return
|
||||
let fio = ''
|
||||
if (pd.type === 'individual' && pd.individual_data) {
|
||||
const d = pd.individual_data
|
||||
fio = [d.last_name, d.first_name, d.middle_name].filter(Boolean).join(' ')
|
||||
} else if (pd.type === 'organization' && pd.organization_data) {
|
||||
fio = (pd.organization_data as any).short_name ?? username
|
||||
} else if (pd.type === 'entrepreneur' && pd.entrepreneur_data) {
|
||||
const d = pd.entrepreneur_data as any
|
||||
fio = [d.last_name, d.first_name, d.middle_name].filter(Boolean).join(' ')
|
||||
}
|
||||
if (fio) fioCache.value.set(username, fio)
|
||||
} catch {
|
||||
// молча — username остаётся как fallback
|
||||
}
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
try {
|
||||
if (route.query.process_type) {
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import { Queries } from '@coopenomics/sdk';
|
||||
import { client } from 'src/shared/api/client';
|
||||
import type { AdminOfferPage, AdminOfferStatusView } from '../types';
|
||||
|
||||
export interface ListAllOffersVariables {
|
||||
statuses?: AdminOfferStatusView[];
|
||||
supplier_account?: string;
|
||||
page?: number;
|
||||
limit?: number;
|
||||
sortBy?: string;
|
||||
sortOrder?: 'ASC' | 'DESC';
|
||||
}
|
||||
|
||||
/**
|
||||
* Реестр всех предложений кооператива любого статуса (стол администратора,
|
||||
* Offer:read:all). Фильтры (статус/поставщик) и пагинация — серверные,
|
||||
* передаются единым input'ом.
|
||||
*/
|
||||
export async function fetchAllOffers(
|
||||
variables: ListAllOffersVariables = {},
|
||||
): Promise<AdminOfferPage> {
|
||||
const { page, limit, sortBy, sortOrder, statuses, supplier_account } = variables;
|
||||
const { [Queries.Marketplace.ListAllOffers.name]: result } = await client.Query(
|
||||
Queries.Marketplace.ListAllOffers.query,
|
||||
{
|
||||
variables: {
|
||||
input: {
|
||||
statuses,
|
||||
supplier_account,
|
||||
page: page ?? 1,
|
||||
limit: limit ?? 50,
|
||||
sortBy: sortBy ?? 'created_at',
|
||||
sortOrder: sortOrder ?? 'DESC',
|
||||
},
|
||||
},
|
||||
},
|
||||
);
|
||||
// Zeus отдаёт DateTime как unknown; сужаем скалярную дату до строки во view-типе.
|
||||
return result as AdminOfferPage;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './ui';
|
||||
export * from './types';
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Реестр всех предложений кооператива (стол администратора).
|
||||
* Источник истины — Zeus-вывод операции marketplaceListAllOffers из @coopenomics/sdk.
|
||||
*/
|
||||
import { Queries } from '@coopenomics/sdk';
|
||||
|
||||
type _RawOfferPage =
|
||||
Queries.Marketplace.ListAllOffers.IOutput['marketplaceListAllOffers'];
|
||||
|
||||
type _RawOffer = _RawOfferPage['items'][number];
|
||||
|
||||
/**
|
||||
* Zeus маппит DateTime в `unknown`. Структуру/enum'ы оставляем из Zeus, но
|
||||
* скалярную дату создания переопределяем на строку для форматирования в UI.
|
||||
*/
|
||||
export type AdminOfferView = Omit<_RawOffer, 'created_at'> & {
|
||||
created_at: string;
|
||||
};
|
||||
|
||||
/** Страница предложений: обёртка из Zeus, но items со строгой датой создания. */
|
||||
export type AdminOfferPage = Omit<_RawOfferPage, 'items'> & {
|
||||
items: AdminOfferView[];
|
||||
};
|
||||
|
||||
/** Доменный статус предложения как строковый литерал (совпадает с Zeus-enum'ом). */
|
||||
export type AdminOfferStatusView = `${AdminOfferView['status']}`;
|
||||
@@ -0,0 +1,254 @@
|
||||
<script lang="ts" setup>
|
||||
/**
|
||||
* Реестр всех предложений кооператива (стол администратора).
|
||||
* Backend: marketplaceListAllOffers (Offer:read:all) — все предложения любого
|
||||
* статуса (опубликованные/снятые/отклонённые/на модерации), всех поставщиков.
|
||||
* Отдельно от «Модерации» (там только то, что прямо сейчас ждёт решения).
|
||||
* Клик по строке открывает readonly-карточку предложения; на эти же карточки
|
||||
* ведёт переход «Открыть предложение» из реестра заказов.
|
||||
*/
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { FailAlert } from 'src/shared/api';
|
||||
import { formatAsset2Digits } from 'src/shared/lib/utils/formatAsset2Digits';
|
||||
import { marketplaceUnitShort } from 'src/shared/lib/consts/marketplace-units';
|
||||
import { useSystemStore } from 'src/entities/System/model';
|
||||
import { useFioCache } from 'src/shared/lib/account/useFioCache';
|
||||
import { BaseBadge, EmptyState } from 'src/shared/ui/base';
|
||||
import type { BaseBadgeVariant } from 'src/shared/ui/base';
|
||||
import { EntityIdBadge } from 'src/shared/ui';
|
||||
import { PageHint } from 'src/shared/ui/domain';
|
||||
import { fetchAllOffers } from '../api';
|
||||
import type { AdminOfferView, AdminOfferStatusView } from '../types';
|
||||
|
||||
const { info } = useSystemStore();
|
||||
const router = useRouter();
|
||||
const { fioCache, enrichFio } = useFioCache();
|
||||
|
||||
const items = ref<AdminOfferView[]>([]);
|
||||
const loading = ref(false);
|
||||
const statusFilter = ref<AdminOfferStatusView[]>([]);
|
||||
const pagination = ref({ page: 1, rowsPerPage: 50, rowsNumber: 0 });
|
||||
|
||||
const OFFER_STATUS: Record<string, { label: string; variant: BaseBadgeVariant }> = {
|
||||
PENDING_MODERATION: { label: 'На модерации', variant: 'warn' },
|
||||
ACTIVE: { label: 'Опубликовано', variant: 'pos' },
|
||||
REJECTED: { label: 'Отклонено', variant: 'neg' },
|
||||
WITHDRAWN: { label: 'Снято с публикации', variant: 'neutral' },
|
||||
};
|
||||
const ALL_STATUSES = Object.keys(OFFER_STATUS) as AdminOfferStatusView[];
|
||||
|
||||
function statusLabel(s: string): string {
|
||||
return OFFER_STATUS[s]?.label ?? s;
|
||||
}
|
||||
function statusVariant(s: string): BaseBadgeVariant {
|
||||
return OFFER_STATUS[s]?.variant ?? 'neutral';
|
||||
}
|
||||
|
||||
const columns = [
|
||||
{ name: 'status', align: 'left' as const, label: 'Статус', field: 'status' },
|
||||
{ name: 'offer', align: 'left' as const, label: 'Предложение', field: 'id' },
|
||||
{ name: 'product', align: 'left' as const, label: 'Товар', field: 'product_name' },
|
||||
{ name: 'supplier', align: 'left' as const, label: 'Поставщик', field: 'supplier_account' },
|
||||
{ name: 'price', align: 'right' as const, label: 'Цена', field: 'price_per_unit' },
|
||||
{ name: 'available', align: 'right' as const, label: 'Доступно', field: 'quantity_available' },
|
||||
{ name: 'created', align: 'left' as const, label: 'Создано', field: 'created_at' },
|
||||
];
|
||||
|
||||
function isStatusActive(s: AdminOfferStatusView): boolean {
|
||||
return statusFilter.value.includes(s);
|
||||
}
|
||||
function toggleStatus(s: AdminOfferStatusView): void {
|
||||
statusFilter.value = isStatusActive(s)
|
||||
? statusFilter.value.filter((x) => x !== s)
|
||||
: [...statusFilter.value, s];
|
||||
void reload();
|
||||
}
|
||||
function resetFilters(): void {
|
||||
if (!statusFilter.value.length) return;
|
||||
statusFilter.value = [];
|
||||
void reload();
|
||||
}
|
||||
|
||||
function shortId(id: string | null | undefined): string {
|
||||
return id ? id.slice(0, 8) : '—';
|
||||
}
|
||||
function unitLabel(o: AdminOfferView): string {
|
||||
return marketplaceUnitShort(o.unit_of_measure);
|
||||
}
|
||||
function formatPrice(v: string | null | undefined): string {
|
||||
return v ? formatAsset2Digits(String(v)) : '—';
|
||||
}
|
||||
function supplierTitle(o: AdminOfferView): string {
|
||||
return fioCache.value.get(o.supplier_account) || o.supplier_account || '—';
|
||||
}
|
||||
function formatDate(d: unknown): string {
|
||||
if (d === null || d === undefined) return '—';
|
||||
const parsed = new Date(String(d));
|
||||
return Number.isNaN(parsed.getTime())
|
||||
? String(d)
|
||||
: parsed.toLocaleString('ru-RU', {
|
||||
day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit',
|
||||
});
|
||||
}
|
||||
|
||||
function goToOffer(o: AdminOfferView): void {
|
||||
if (!o.id) return;
|
||||
void router.push({
|
||||
name: 'marketplace-admin-offer-detail',
|
||||
params: { coopname: info.coopname, offerId: o.id },
|
||||
});
|
||||
}
|
||||
|
||||
let lastRequestId = 0;
|
||||
|
||||
async function reload(): Promise<void> {
|
||||
pagination.value.page = 1;
|
||||
await load();
|
||||
}
|
||||
|
||||
async function load(): Promise<void> {
|
||||
const myId = ++lastRequestId;
|
||||
loading.value = true;
|
||||
try {
|
||||
const resp = await fetchAllOffers({
|
||||
statuses: statusFilter.value.length ? statusFilter.value : undefined,
|
||||
page: pagination.value.page,
|
||||
limit: pagination.value.rowsPerPage,
|
||||
sortOrder: 'DESC',
|
||||
});
|
||||
if (myId !== lastRequestId) return;
|
||||
items.value = resp.items ?? [];
|
||||
pagination.value.rowsNumber = resp.totalCount ?? 0;
|
||||
void enrichFio(items.value.map((o) => o.supplier_account));
|
||||
} catch (e) {
|
||||
if (myId === lastRequestId) FailAlert(e, 'Не удалось загрузить реестр предложений');
|
||||
} finally {
|
||||
if (myId === lastRequestId) loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function onRequest(props: { pagination: { page: number; rowsPerPage: number; rowsNumber?: number } }): void {
|
||||
pagination.value = {
|
||||
page: props.pagination.page,
|
||||
rowsPerPage: props.pagination.rowsPerPage,
|
||||
rowsNumber: props.pagination.rowsNumber ?? pagination.value.rowsNumber,
|
||||
};
|
||||
void load();
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
void load();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template lang="pug">
|
||||
q-page.admin-offers(role="region", aria-label="Реестр предложений кооператива")
|
||||
PageHint(storage-key="mp:admin-offers:banner-dismissed")
|
||||
| Все предложения поставщиков кооператива любого статуса — опубликованные, снятые, отклонённые и ждущие модерации. Нажмите на предложение, чтобы открыть его карточку. Модерация ждущих решения — на отдельной странице.
|
||||
|
||||
.admin-offers__chips(role="group", aria-label="Фильтр по статусу")
|
||||
.chip(
|
||||
v-for="s in ALL_STATUSES",
|
||||
:key="s",
|
||||
:class="isStatusActive(s) ? 'chip--accent' : 'chip--neutral'",
|
||||
role="button",
|
||||
tabindex="0",
|
||||
@click="toggleStatus(s)",
|
||||
@keydown.enter="toggleStatus(s)"
|
||||
) {{ statusLabel(s) }}
|
||||
.chip.chip--reset(
|
||||
v-if="statusFilter.length",
|
||||
role="button",
|
||||
tabindex="0",
|
||||
@click="resetFilters",
|
||||
@keydown.enter="resetFilters"
|
||||
)
|
||||
q-icon(name="close", size="14px")
|
||||
| Сбросить
|
||||
|
||||
q-card.q-mt-md(flat)
|
||||
q-table.full-height(
|
||||
flat,
|
||||
:rows="items",
|
||||
:columns="columns",
|
||||
row-key="id",
|
||||
:loading="loading",
|
||||
:pagination="pagination",
|
||||
:rows-per-page-options="[25, 50, 100, 200]",
|
||||
no-data-label="Предложения не найдены",
|
||||
@request="onRequest",
|
||||
@row-click="(_evt, row) => goToOffer(row)"
|
||||
)
|
||||
template(#body-cell-status="props")
|
||||
q-td(:props="props")
|
||||
BaseBadge(:variant="statusVariant(props.row.status)") {{ statusLabel(props.row.status) }}
|
||||
template(#body-cell-offer="props")
|
||||
q-td(:props="props")
|
||||
EntityIdBadge(:rawId="shortId(props.row.id)", copy-on-click)
|
||||
template(#body-cell-product="props")
|
||||
q-td(:props="props") {{ props.row.product_name || 'Товар по предложению' }}
|
||||
template(#body-cell-supplier="props")
|
||||
q-td(:props="props") {{ supplierTitle(props.row) }}
|
||||
template(#body-cell-price="props")
|
||||
q-td.text-right.font-monospace(:props="props") {{ formatPrice(props.row.price_per_unit) }}
|
||||
template(#body-cell-available="props")
|
||||
q-td.text-right(:props="props") {{ props.row.unlimited_flag ? '∞' : props.row.quantity_available }} {{ unitLabel(props.row) }}
|
||||
template(#body-cell-created="props")
|
||||
q-td(:props="props") {{ formatDate(props.row.created_at) }}
|
||||
template(#no-data)
|
||||
.admin-offers__nodata
|
||||
EmptyState(
|
||||
title="Предложений нет",
|
||||
body="Предложений по выбранным фильтрам не найдено."
|
||||
)
|
||||
template(#icon)
|
||||
q-icon(name="storefront", size="48px")
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.admin-offers {
|
||||
padding: var(--p-6, 24px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--p-4, 16px);
|
||||
|
||||
&__nodata {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
&__chips {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--p-2, 8px);
|
||||
|
||||
.chip {
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
height: 28px;
|
||||
padding: 0 12px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
// Строки кликабельны (ведут на карточку) — курсор-указатель как аффорданс.
|
||||
:deep(.q-table tbody tr) {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.font-monospace {
|
||||
font-family: 'JetBrains Mono', 'Courier New', monospace;
|
||||
letter-spacing: 0.03em;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.admin-offers {
|
||||
padding: var(--p-4, 16px);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1 @@
|
||||
export { default as AdminOffersPage } from './AdminOffersPage.vue';
|
||||
@@ -0,0 +1,44 @@
|
||||
import { ref } from 'vue'
|
||||
import { useAccountStore } from 'src/entities/Account'
|
||||
|
||||
/**
|
||||
* Кэш ФИО пайщиков по username — общий для реестров (процессы/заказы/предложения),
|
||||
* где из цепочки приходит служебный аккаунт, а показывать нужно человеческое имя
|
||||
* (НЕ braname). enrichFio догружает недостающие имена через accountStore и
|
||||
* кладёт в кэш; в UI используется `fioCache.get(username) || username`.
|
||||
*/
|
||||
export function useFioCache() {
|
||||
const accountStore = useAccountStore()
|
||||
const fioCache = ref(new Map<string, string>())
|
||||
|
||||
async function enrichFio(rawUsernames: (string | null | undefined)[]): Promise<void> {
|
||||
const usernames = [
|
||||
...new Set(rawUsernames.filter((u): u is string => !!u && !fioCache.value.has(u))),
|
||||
]
|
||||
if (!usernames.length) return
|
||||
await Promise.allSettled(
|
||||
usernames.map(async (username) => {
|
||||
try {
|
||||
const acc = await accountStore.getAccount(username)
|
||||
const pd = acc?.private_account
|
||||
if (!pd) return
|
||||
let fio = ''
|
||||
if (pd.type === 'individual' && pd.individual_data) {
|
||||
const d = pd.individual_data
|
||||
fio = [d.last_name, d.first_name, d.middle_name].filter(Boolean).join(' ')
|
||||
} else if (pd.type === 'organization' && pd.organization_data) {
|
||||
fio = (pd.organization_data as any).short_name ?? username
|
||||
} else if (pd.type === 'entrepreneur' && pd.entrepreneur_data) {
|
||||
const d = pd.entrepreneur_data as any
|
||||
fio = [d.last_name, d.first_name, d.middle_name].filter(Boolean).join(' ')
|
||||
}
|
||||
if (fio) fioCache.value.set(username, fio)
|
||||
} catch {
|
||||
// молча — username остаётся как fallback
|
||||
}
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
return { fioCache, enrichFio }
|
||||
}
|
||||
@@ -72,6 +72,8 @@ export * as MarketplaceCppStatus from './marketplaceCppStatus'
|
||||
export * as ListSupplierOrders from './listSupplierOrders'
|
||||
/** Эпик 3 / Story 3.4: собственные Offer'ы поставщика (стол поставщика, все статусы) */
|
||||
export * as ListMyOffers from './listMyOffers'
|
||||
/** Реестр всех предложений кооператива любого статуса (стол администратора, Offer:read:all) */
|
||||
export * as ListAllOffers from './listAllOffers'
|
||||
/** Доступные категории и типы товаров для кооператива (admin-настройка whitelist'а) */
|
||||
export * as GetAvailableCategories from './getAvailableCategories'
|
||||
/** Эпик 16: полный список категорий кооператива — общие baseline + собственные */
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
import { marketplaceOfferPaginationSelector } from '../../selectors/marketplace/marketplaceOfferPaginationSelector'
|
||||
import { $, type GraphQLTypes, type InputType, Selector } from '../../zeus/index'
|
||||
|
||||
export const name = 'marketplaceListAllOffers'
|
||||
|
||||
export const query = Selector('Query')({
|
||||
[name]: [{ input: $('input', 'MarketplaceListAllOffersInput') }, marketplaceOfferPaginationSelector],
|
||||
})
|
||||
|
||||
export type IOutput = InputType<GraphQLTypes['Query'], typeof query>
|
||||
@@ -795,6 +795,9 @@ export const AllTypesProps: Record<string,any> = {
|
||||
MarketplaceKUStatus: "enum" as const,
|
||||
MarketplaceListAidsInput:{
|
||||
|
||||
},
|
||||
MarketplaceListAllOffersInput:{
|
||||
statuses:"MarketplaceOfferStatus"
|
||||
},
|
||||
MarketplaceListAplReceptionsByBranameInput:{
|
||||
|
||||
@@ -2163,6 +2166,9 @@ export const AllTypesProps: Record<string,any> = {
|
||||
marketplaceListAids:{
|
||||
data:"MarketplaceListAidsInput"
|
||||
},
|
||||
marketplaceListAllOffers:{
|
||||
input:"MarketplaceListAllOffersInput"
|
||||
},
|
||||
marketplaceListAllOrders:{
|
||||
input:"MarketplaceListOrdersInput",
|
||||
options:"PaginationInput"
|
||||
@@ -5850,6 +5856,7 @@ export const ReturnTypes: Record<string,any> = {
|
||||
marketplaceIssueActChairmanSignablePayload:"GeneratedDocument",
|
||||
marketplaceIssueActOrdererSignablePayload:"DocumentAggregate",
|
||||
marketplaceListAids:"MarketplaceAid",
|
||||
marketplaceListAllOffers:"MarketplaceOfferPaginationResult",
|
||||
marketplaceListAllOrders:"MarketplaceOrderPaginationResult",
|
||||
marketplaceListAplReceptionsAsSupplier:"MarketplaceAplReception",
|
||||
marketplaceListAplReceptionsByBraname:"MarketplaceAplReception",
|
||||
|
||||
@@ -7193,6 +7193,21 @@ export type ValueTypes = {
|
||||
["MarketplaceListAidsInput"]: {
|
||||
/** Показать заявки только этого получателя (по умолчанию — свои). */
|
||||
username?: string | undefined | null | Variable<any, string>
|
||||
};
|
||||
/** Параметры фильтрации реестра всех предложений кооператива (стол администратора). */
|
||||
["MarketplaceListAllOffersInput"]: {
|
||||
/** Количество элементов на странице */
|
||||
limit: number | Variable<any, string>,
|
||||
/** Номер страницы */
|
||||
page: number | Variable<any, string>,
|
||||
/** Ключ сортировки (например, "name") */
|
||||
sortBy?: string | undefined | null | Variable<any, string>,
|
||||
/** Направление сортировки ("ASC" или "DESC") */
|
||||
sortOrder: string | Variable<any, string>,
|
||||
/** Один или несколько статусов предложения, по которым нужно отфильтровать список. */
|
||||
statuses?: Array<ValueTypes["MarketplaceOfferStatus"]> | undefined | null | Variable<any, string>,
|
||||
/** Фильтр по аккаунту поставщика. */
|
||||
supplier_account?: string | undefined | null | Variable<any, string>
|
||||
};
|
||||
["MarketplaceListAplReceptionsByBranameInput"]: {
|
||||
/** Идентификатор КУ-получателя. */
|
||||
@@ -10369,6 +10384,7 @@ marketplaceGetUserRequests?: [{ data?: ValueTypes["GetUserRequestsInput"] | unde
|
||||
marketplaceIssueActChairmanSignablePayload?: [{ data: ValueTypes["MarketplaceIssueActPayloadInput"] | Variable<any, string>},ValueTypes["GeneratedDocument"]],
|
||||
marketplaceIssueActOrdererSignablePayload?: [{ data: ValueTypes["MarketplaceIssueActPayloadInput"] | Variable<any, string>},ValueTypes["DocumentAggregate"]],
|
||||
marketplaceListAids?: [{ data?: ValueTypes["MarketplaceListAidsInput"] | undefined | null | Variable<any, string>},ValueTypes["MarketplaceAid"]],
|
||||
marketplaceListAllOffers?: [{ input?: ValueTypes["MarketplaceListAllOffersInput"] | undefined | null | Variable<any, string>},ValueTypes["MarketplaceOfferPaginationResult"]],
|
||||
marketplaceListAllOrders?: [{ input?: ValueTypes["MarketplaceListOrdersInput"] | undefined | null | Variable<any, string>, options?: ValueTypes["PaginationInput"] | undefined | null | Variable<any, string>},ValueTypes["MarketplaceOrderPaginationResult"]],
|
||||
/** Список актов приёмки, ожидающих подписи текущего поставщика. */
|
||||
marketplaceListAplReceptionsAsSupplier?:ValueTypes["MarketplaceAplReception"],
|
||||
@@ -17953,6 +17969,21 @@ export type ResolverInputTypes = {
|
||||
["MarketplaceListAidsInput"]: {
|
||||
/** Показать заявки только этого получателя (по умолчанию — свои). */
|
||||
username?: string | undefined | null
|
||||
};
|
||||
/** Параметры фильтрации реестра всех предложений кооператива (стол администратора). */
|
||||
["MarketplaceListAllOffersInput"]: {
|
||||
/** Количество элементов на странице */
|
||||
limit: number,
|
||||
/** Номер страницы */
|
||||
page: number,
|
||||
/** Ключ сортировки (например, "name") */
|
||||
sortBy?: string | undefined | null,
|
||||
/** Направление сортировки ("ASC" или "DESC") */
|
||||
sortOrder: string,
|
||||
/** Один или несколько статусов предложения, по которым нужно отфильтровать список. */
|
||||
statuses?: Array<ResolverInputTypes["MarketplaceOfferStatus"]> | undefined | null,
|
||||
/** Фильтр по аккаунту поставщика. */
|
||||
supplier_account?: string | undefined | null
|
||||
};
|
||||
["MarketplaceListAplReceptionsByBranameInput"]: {
|
||||
/** Идентификатор КУ-получателя. */
|
||||
@@ -21011,6 +21042,7 @@ marketplaceGetUserRequests?: [{ data?: ResolverInputTypes["GetUserRequestsInput"
|
||||
marketplaceIssueActChairmanSignablePayload?: [{ data: ResolverInputTypes["MarketplaceIssueActPayloadInput"]},ResolverInputTypes["GeneratedDocument"]],
|
||||
marketplaceIssueActOrdererSignablePayload?: [{ data: ResolverInputTypes["MarketplaceIssueActPayloadInput"]},ResolverInputTypes["DocumentAggregate"]],
|
||||
marketplaceListAids?: [{ data?: ResolverInputTypes["MarketplaceListAidsInput"] | undefined | null},ResolverInputTypes["MarketplaceAid"]],
|
||||
marketplaceListAllOffers?: [{ input?: ResolverInputTypes["MarketplaceListAllOffersInput"] | undefined | null},ResolverInputTypes["MarketplaceOfferPaginationResult"]],
|
||||
marketplaceListAllOrders?: [{ input?: ResolverInputTypes["MarketplaceListOrdersInput"] | undefined | null, options?: ResolverInputTypes["PaginationInput"] | undefined | null},ResolverInputTypes["MarketplaceOrderPaginationResult"]],
|
||||
/** Список актов приёмки, ожидающих подписи текущего поставщика. */
|
||||
marketplaceListAplReceptionsAsSupplier?:ResolverInputTypes["MarketplaceAplReception"],
|
||||
@@ -28341,6 +28373,21 @@ export type ModelTypes = {
|
||||
["MarketplaceListAidsInput"]: {
|
||||
/** Показать заявки только этого получателя (по умолчанию — свои). */
|
||||
username?: string | undefined | null
|
||||
};
|
||||
/** Параметры фильтрации реестра всех предложений кооператива (стол администратора). */
|
||||
["MarketplaceListAllOffersInput"]: {
|
||||
/** Количество элементов на странице */
|
||||
limit: number,
|
||||
/** Номер страницы */
|
||||
page: number,
|
||||
/** Ключ сортировки (например, "name") */
|
||||
sortBy?: string | undefined | null,
|
||||
/** Направление сортировки ("ASC" или "DESC") */
|
||||
sortOrder: string,
|
||||
/** Один или несколько статусов предложения, по которым нужно отфильтровать список. */
|
||||
statuses?: Array<ModelTypes["MarketplaceOfferStatus"]> | undefined | null,
|
||||
/** Фильтр по аккаунту поставщика. */
|
||||
supplier_account?: string | undefined | null
|
||||
};
|
||||
["MarketplaceListAplReceptionsByBranameInput"]: {
|
||||
/** Идентификатор КУ-получателя. */
|
||||
@@ -32016,6 +32063,8 @@ export type ModelTypes = {
|
||||
marketplaceIssueActOrdererSignablePayload: ModelTypes["DocumentAggregate"],
|
||||
/** Заявки на материальную помощь: свои — для доверенного; все заявки кооператива — для администратора. */
|
||||
marketplaceListAids: Array<ModelTypes["MarketplaceAid"]>,
|
||||
/** Реестр всех предложений кооператива любого статуса (стол администратора). */
|
||||
marketplaceListAllOffers: ModelTypes["MarketplaceOfferPaginationResult"],
|
||||
/** Реестр всех заказов кооператива с их текущими статусами (стол администратора). */
|
||||
marketplaceListAllOrders: ModelTypes["MarketplaceOrderPaginationResult"],
|
||||
/** Список актов приёмки, ожидающих подписи текущего поставщика. */
|
||||
@@ -39708,6 +39757,21 @@ export type GraphQLTypes = {
|
||||
["MarketplaceListAidsInput"]: {
|
||||
/** Показать заявки только этого получателя (по умолчанию — свои). */
|
||||
username?: string | undefined | null
|
||||
};
|
||||
/** Параметры фильтрации реестра всех предложений кооператива (стол администратора). */
|
||||
["MarketplaceListAllOffersInput"]: {
|
||||
/** Количество элементов на странице */
|
||||
limit: number,
|
||||
/** Номер страницы */
|
||||
page: number,
|
||||
/** Ключ сортировки (например, "name") */
|
||||
sortBy?: string | undefined | null,
|
||||
/** Направление сортировки ("ASC" или "DESC") */
|
||||
sortOrder: string,
|
||||
/** Один или несколько статусов предложения, по которым нужно отфильтровать список. */
|
||||
statuses?: Array<GraphQLTypes["MarketplaceOfferStatus"]> | undefined | null,
|
||||
/** Фильтр по аккаунту поставщика. */
|
||||
supplier_account?: string | undefined | null
|
||||
};
|
||||
["MarketplaceListAplReceptionsByBranameInput"]: {
|
||||
/** Идентификатор КУ-получателя. */
|
||||
@@ -43653,6 +43717,8 @@ export type GraphQLTypes = {
|
||||
marketplaceIssueActOrdererSignablePayload: GraphQLTypes["DocumentAggregate"],
|
||||
/** Заявки на материальную помощь: свои — для доверенного; все заявки кооператива — для администратора. */
|
||||
marketplaceListAids: Array<GraphQLTypes["MarketplaceAid"]>,
|
||||
/** Реестр всех предложений кооператива любого статуса (стол администратора). */
|
||||
marketplaceListAllOffers: GraphQLTypes["MarketplaceOfferPaginationResult"],
|
||||
/** Реестр всех заказов кооператива с их текущими статусами (стол администратора). */
|
||||
marketplaceListAllOrders: GraphQLTypes["MarketplaceOrderPaginationResult"],
|
||||
/** Список актов приёмки, ожидающих подписи текущего поставщика. */
|
||||
@@ -46240,6 +46306,7 @@ type ZEUS_VARIABLES = {
|
||||
["MarketplaceIssueActSignedMetaDocumentInput"]: ValueTypes["MarketplaceIssueActSignedMetaDocumentInput"];
|
||||
["MarketplaceKUStatus"]: ValueTypes["MarketplaceKUStatus"];
|
||||
["MarketplaceListAidsInput"]: ValueTypes["MarketplaceListAidsInput"];
|
||||
["MarketplaceListAllOffersInput"]: ValueTypes["MarketplaceListAllOffersInput"];
|
||||
["MarketplaceListAplReceptionsByBranameInput"]: ValueTypes["MarketplaceListAplReceptionsByBranameInput"];
|
||||
["MarketplaceListCatalogInput"]: ValueTypes["MarketplaceListCatalogInput"];
|
||||
["MarketplaceListConsolidatedRequestsInput"]: ValueTypes["MarketplaceListConsolidatedRequestsInput"];
|
||||
|
||||
Reference in New Issue
Block a user