summaryrefslogtreecommitdiff
path: root/src-migrate/services/product.ts
blob: fa9dae5435040f5be9b512ce112fe8b0cd9f329a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import { IProduct, IProductDetail } from '~/types/product';
import snakeCase from 'snakecase-keys';
import odooApi from '~/libs/odooApi';
import { ICategoryBreadcrumb } from '~/types/category';

const SELF_HOST = process.env.NEXT_PUBLIC_SELF_HOST;

export const getProductById = async (
  id: string,
  tier: string
): Promise<IProductDetail | null> => {
  const url = `${SELF_HOST}/api/shop/product-detail`;
  const params = new URLSearchParams({ id, auth: tier });
  return await fetch(`${url}?${params.toString()}`)
    .then((res) => res.json())
    .then((res) => {
      if (res.length > 0) return snakeCase(res[0]) as IProductDetail;
      return null;
    });
};

export interface GetProductSimilarProps {
  name: string;
  except?: {
    productId?: number;
    manufactureId?: number;
  };
  limit?: number;
}

export interface GetProductSimilarRes {
  products: IProduct[];
  num_found: number;
  num_found_exact: boolean;
  start: number;
}

export const getProductSimilar = async ({
  name,
  except,
  limit = 30,
}: GetProductSimilarProps): Promise<GetProductSimilarRes> => {
  const query = [
    `q=${name}`,
    'page=1',
    'operation=OR',
    // 'priceFrom=1',
    `source=similar`,
  ];

  if (except?.productId) query.push(`fq=-product_id_i:${except.productId}`);
  if (except?.manufactureId)
    query.push(`fq=-manufacture_id_i:${except.manufactureId}`);

  const url = `${SELF_HOST}/api/shop/search?${query.join('&')}`;

  return await fetch(url)
    .then((res) => res.json())
    .then((res) => snakeCase(res.response));
};

export const getProductCategoryBreadcrumb = async (
  id: number
): Promise<ICategoryBreadcrumb[]> => {
  return await odooApi('GET', `/api/v1/product/${id}/category-breadcrumb`);
};

// =================================================================
// TAMBAHAN BARU: SERVICE FETCH BY LIST ID (UNTUK UPSELL/RELATED)
// =================================================================

export interface GetProductsByIdsProps {
  ids: number[];
}

export const getProductsByIds = async ({
  ids,
}: GetProductsByIdsProps): Promise<GetProductSimilarRes> => {
  if (!ids || ids.length === 0) {
    return { products: [], num_found: 0, num_found_exact: true, start: 0 };
  }

  const idQuery = ids.join(' OR ');

  const query = [
    `q=*`,
    `fq=(id:(${idQuery}) OR product_id_i:(${idQuery}))`,
    'rows=20',
    `source=upsell`,
  ];

  const url = `${SELF_HOST}/api/shop/search?${query.join('&')}`;

  // Request
  const res = await fetch(url).then((res) => res.json());

  // LOG 2: Hasil Pencarian SOLR
  console.group("🔍 2. [Solr Search Result]");
  console.log("Request URL:", url);
  console.log("Requested IDs:", ids);
  
  const foundDocs = res.response?.docs || [];
  const foundIds = foundDocs.map((doc: any) => doc.id || doc.product_id_i);
  
  console.log("Found Products Count:", res.response?.numFound);
  console.log("Found IDs:", foundIds);
  
  // Cek ID mana yang hilang
  const missingIds = ids.filter((reqId) => !foundIds.includes(String(reqId)) && !foundIds.includes(Number(reqId)));
  if (missingIds.length > 0) {
      console.warn("⚠️ MISSING / NOT FOUND IDs:", missingIds);
  } else {
      console.log("✅ All IDs Found!");
  }
  console.groupEnd();

  return snakeCase(res.response);
};