feat: purchase-plans update

This commit is contained in:
ivannoskov
2026-02-03 11:14:53 +03:00
parent 6b16bfa6e2
commit d87d6e2568
6 changed files with 179 additions and 35 deletions

View File

@@ -33,10 +33,17 @@ export const placementsApi = {
.then((response) => response.items),
/**
* Get single placement (deprecated - use getInProject for project-specific data)
* Get single placement (requires project_id in original backend)
* Uses: GET /workspaces/{workspace_id}/projects/{project_id}/placements/{placement_id}
*/
get: (workspaceId: string, placementId: string) =>
api.get<Placement>(`/workspaces/${workspaceId}/placements/${placementId}`),
get: (
workspaceId: string,
placementId: string,
projectId?: string
) =>
api.get<Placement>(
`/workspaces/${workspaceId}/projects/${projectId}/placements/${placementId}`
),
/**
* Get single placement within project
@@ -91,6 +98,47 @@ export const placementsApi = {
data
),
/**
* Create single placement within project (bulk format)
* POST /workspaces/{workspace_id}/projects/{project_id}/placements
*/
createInProject: (
workspaceId: string,
projectId: string,
data: {
creative_id?: string;
channels: Array<{
channel_id: string;
status?: string;
comment?: string;
details?: {
placement_at?: string;
payment_at?: string;
cost?: { type: string; value: number };
cost_before_bargain?: number;
placement_type?: string;
format?: string;
comment?: string;
creative_id?: string;
};
}>;
details?: {
placement_at?: string;
payment_at?: string;
cost?: { type: string; value: number };
cost_before_bargain?: number;
placement_type?: string;
format?: string;
comment?: string;
creative_id?: string;
};
}
) =>
api.post<{ placements: Placement[] }>(
`/workspaces/${workspaceId}/projects/${projectId}/placements`,
data
),
/**
* Update placement
*/

View File

@@ -5,6 +5,7 @@ export interface ColumnConfig {
label: string;
group: string;
editable: boolean;
partialEdit?: boolean;
width?: string;
required?: boolean;
}
@@ -21,10 +22,10 @@ export const COLUMN_GROUPS = [
export const ALL_COLUMNS: ColumnConfig[] = [
// Basic
{ id: "checkbox", label: "", group: "basic", editable: false, required: true },
{ id: "number", label: "", group: "basic", editable: false, required: true },
{ id: "status_deal", label: "Статус сделки", group: "basic", editable: true },
{ id: "status_post", label: "Статус поста", group: "basic", editable: true },
{ id: "checkbox", label: "Чекбокс", group: "basic", editable: false, required: true },
{ id: "number", label: "Номер", group: "basic", editable: false, required: true },
{ id: "status_deal", label: "Статус сделки", group: "basic", editable: true, partialEdit: true },
{ id: "status_post", label: "Статус поста", group: "basic", editable: true, partialEdit: true },
// Content
{ id: "creative", label: "Креатив", group: "content", editable: true },
@@ -32,9 +33,9 @@ export const ALL_COLUMNS: ColumnConfig[] = [
{ id: "post_link", label: "Ссылка на пост", group: "content", editable: false },
// Finance
{ id: "cost", label: "Стоимость", group: "finance", editable: true },
{ id: "cost", label: "Стоимость", group: "finance", editable: true, partialEdit: true },
{ id: "cost_before", label: "Стоимость до торга", group: "finance", editable: true },
{ id: "cost_format", label: "Формат оплаты", group: "finance", editable: true },
{ id: "cost_format", label: "Формат оплаты", group: "finance", editable: true, partialEdit: true },
{ id: "placement_type", label: "Тип закупа", group: "finance", editable: true },
{ id: "discount", label: "% скидки", group: "finance", editable: false },
{ id: "payment_date", label: "Дата оплаты", group: "finance", editable: true },
@@ -54,7 +55,7 @@ export const ALL_COLUMNS: ColumnConfig[] = [
// Calculated
{ id: "cpf", label: "CPF", group: "calculated", editable: false },
{ id: "cpm", label: "CPM", group: "calculated", editable: false },
{ id: "cpm", label: "CPM", group: "calculated", editable: true, partialEdit: true },
{ id: "conversion_24h", label: "Конверсия 24ч", group: "calculated", editable: false },
{ id: "conversion_48h", label: "Конверсия 48ч", group: "calculated", editable: false },
{ id: "conversion_total", label: "Конверсия общ.", group: "calculated", editable: false },

View File

@@ -272,13 +272,13 @@ export const demoAwarePlacementsApi = {
}
return placementsApi.list(workspaceId, params);
},
get: async (workspaceId: string, placementId: string): Promise<Placement> => {
get: async (workspaceId: string, placementId: string, _projectId?: string): Promise<Placement> => {
if (isDemoWorkspace(workspaceId)) {
const placement = demoPlacements.find((p) => p.id === placementId);
if (!placement) throw new Error("Placement not found");
return placement;
}
return placementsApi.get(workspaceId, placementId);
return placementsApi.get(workspaceId, placementId, _projectId);
},
getByProject: async (workspaceId: string, projectId: string): Promise<Placement[]> => {
if (isDemoWorkspace(workspaceId)) {