@webbycrown/webbycommerce 1.2.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. package/README.md +26 -3
  2. package/admin/app.js +3 -0
  3. package/admin/jsconfig.json +20 -0
  4. package/admin/src/components/ApiCollectionsContent.jsx +4626 -0
  5. package/admin/src/components/CompareContent.jsx +300 -0
  6. package/admin/src/components/ConfigureContent.jsx +407 -0
  7. package/admin/src/components/Initializer.jsx +64 -0
  8. package/admin/src/components/LoginRegisterContent.jsx +280 -0
  9. package/admin/src/components/PluginIcon.jsx +6 -0
  10. package/admin/src/components/ShippingTypeContent.jsx +230 -0
  11. package/admin/src/components/SmtpContent.jsx +316 -0
  12. package/admin/src/components/WishlistContent.jsx +273 -0
  13. package/admin/src/index.js +81 -0
  14. package/admin/src/pages/ApiCollections.jsx +169 -0
  15. package/admin/src/pages/Configure.jsx +55 -0
  16. package/admin/src/pages/Settings.jsx +93 -0
  17. package/admin/src/pluginId.js +4 -0
  18. package/{dist/_chunks/en-CiQ97iC8.js → admin/src/translations/en.json} +712 -574
  19. package/bin/setup.js +50 -3
  20. package/package.json +14 -13
  21. package/server/bootstrap.js +3 -0
  22. package/server/register.js +3 -0
  23. package/server/src/bootstrap.js +3826 -0
  24. package/server/src/components/content-block.json +37 -0
  25. package/server/src/components/shipping-zone-location.json +27 -0
  26. package/server/src/config/index.js +7 -0
  27. package/server/src/content-types/address/index.js +7 -0
  28. package/server/src/content-types/address/schema.json +74 -0
  29. package/server/src/content-types/cart/index.js +61 -0
  30. package/server/src/content-types/cart-item/index.js +79 -0
  31. package/server/src/content-types/compare.js +73 -0
  32. package/server/src/content-types/coupon/index.js +7 -0
  33. package/server/src/content-types/coupon/schema.json +67 -0
  34. package/server/src/content-types/index.js +42 -0
  35. package/server/src/content-types/order/index.js +7 -0
  36. package/server/src/content-types/order/schema.json +121 -0
  37. package/server/src/content-types/payment-transaction/index.js +7 -0
  38. package/server/src/content-types/payment-transaction/schema.json +73 -0
  39. package/server/src/content-types/product/index.js +7 -0
  40. package/server/src/content-types/product/schema.json +104 -0
  41. package/server/src/content-types/product-attribute/index.js +7 -0
  42. package/server/src/content-types/product-attribute/schema.json +80 -0
  43. package/server/src/content-types/product-attribute-value/index.js +7 -0
  44. package/server/src/content-types/product-attribute-value/schema.json +52 -0
  45. package/server/src/content-types/product-category/index.js +7 -0
  46. package/server/src/content-types/product-category/schema.json +54 -0
  47. package/server/src/content-types/product-tag/index.js +7 -0
  48. package/server/src/content-types/product-tag/schema.json +38 -0
  49. package/server/src/content-types/product-variation/index.js +7 -0
  50. package/server/src/content-types/product-variation/schema.json +74 -0
  51. package/server/src/content-types/shipping-method/index.js +7 -0
  52. package/server/src/content-types/shipping-method/schema.json +91 -0
  53. package/server/src/content-types/shipping-rate/index.js +7 -0
  54. package/server/src/content-types/shipping-rate/schema.json +73 -0
  55. package/server/src/content-types/shipping-rule/index.js +7 -0
  56. package/server/src/content-types/shipping-rule/schema.json +84 -0
  57. package/server/src/content-types/shipping-zone/index.js +7 -0
  58. package/server/src/content-types/shipping-zone/schema.json +57 -0
  59. package/server/src/content-types/wishlist.js +66 -0
  60. package/server/src/controllers/address.js +374 -0
  61. package/server/src/controllers/auth.js +1409 -0
  62. package/server/src/controllers/cart.js +337 -0
  63. package/server/src/controllers/category.js +388 -0
  64. package/server/src/controllers/compare.js +246 -0
  65. package/server/src/controllers/controller.js +168 -0
  66. package/server/src/controllers/ecommerce.js +20 -0
  67. package/server/src/controllers/index.js +34 -0
  68. package/server/src/controllers/order.js +1100 -0
  69. package/server/src/controllers/payment.js +243 -0
  70. package/server/src/controllers/product.js +1006 -0
  71. package/server/src/controllers/productTag.js +370 -0
  72. package/server/src/controllers/productVariation.js +181 -0
  73. package/server/src/controllers/shipping.js +1046 -0
  74. package/server/src/controllers/wishlist.js +332 -0
  75. package/server/src/destroy.js +6 -0
  76. package/server/src/index.js +26 -0
  77. package/server/src/middlewares/index.js +4 -0
  78. package/server/src/policies/index.js +4 -0
  79. package/server/src/register.js +67 -0
  80. package/server/src/routes/index.js +1130 -0
  81. package/server/src/services/cart.js +531 -0
  82. package/server/src/services/compare.js +300 -0
  83. package/server/src/services/index.js +16 -0
  84. package/server/src/services/service.js +19 -0
  85. package/server/src/services/shipping.js +513 -0
  86. package/server/src/services/wishlist.js +238 -0
  87. package/server/src/utils/check-ecommerce-permission.js +204 -0
  88. package/server/src/utils/extend-user-schema.js +161 -0
  89. package/server/src/utils/seed-data.js +639 -0
  90. package/server/src/utils/send-email.js +98 -0
  91. package/strapi-server.js +1 -6
  92. package/dist/_chunks/Settings-DZXAkI24.js +0 -31539
  93. package/dist/_chunks/Settings-yLx-YvVy.mjs +0 -31520
  94. package/dist/_chunks/en-DE15m4xZ.mjs +0 -574
  95. package/dist/_chunks/index-CXGrFKp6.mjs +0 -128
  96. package/dist/_chunks/index-DgocXUgC.js +0 -127
  97. package/dist/admin/index.js +0 -3
  98. package/dist/admin/index.mjs +0 -4
  99. package/dist/robots.txt +0 -3
  100. package/dist/server/index.js +0 -27078
  101. package/dist/uploads/.gitkeep +0 -0
  102. package/dist/uploads/accessories_category_2a5631094b.jpeg +0 -0
  103. package/dist/uploads/beauty_personal_care_category_57f8a8f1e3.jpeg +0 -0
  104. package/dist/uploads/books_category_a9a253eada.jpeg +0 -0
  105. package/dist/uploads/classic_cotton_tshirt_1_cd713425f6.png +0 -0
  106. package/dist/uploads/clothing_category_d5c60ef07b.jpeg +0 -0
  107. package/dist/uploads/daviddoe_strapi_adbcd41787.jpeg +0 -0
  108. package/dist/uploads/electronics_category_fc3e5ef571.jpeg +0 -0
  109. package/dist/uploads/ergonomic_office_chair_1_c751cffb07.png +0 -0
  110. package/dist/uploads/home_garden_category_4f6eb3f8d6.jpeg +0 -0
  111. package/dist/uploads/istockphoto_1188462138_612x612_11f295b9c0.jpg +0 -0
  112. package/dist/uploads/istockphoto_1188462138_612x612_396fb272fd.jpg +0 -0
  113. package/dist/uploads/large_daviddoe_strapi_adbcd41787.jpeg +0 -0
  114. package/dist/uploads/leather_travel_backpack_1_238bc1ae4d.png +0 -0
  115. package/dist/uploads/mechanical_keyboard_pro_1_0cd391a6ac.png +0 -0
  116. package/dist/uploads/medium_classic_cotton_tshirt_1_cd713425f6.png +0 -0
  117. package/dist/uploads/medium_daviddoe_strapi_adbcd41787.jpeg +0 -0
  118. package/dist/uploads/medium_ergonomic_office_chair_1_c751cffb07.png +0 -0
  119. package/dist/uploads/medium_leather_travel_backpack_1_238bc1ae4d.png +0 -0
  120. package/dist/uploads/medium_mechanical_keyboard_pro_1_0cd391a6ac.png +0 -0
  121. package/dist/uploads/medium_smart_watch_series_5_1_cdc2511fb7.png +0 -0
  122. package/dist/uploads/medium_smartphone_x_pro_1_c3f0cbd080.png +0 -0
  123. package/dist/uploads/medium_the_great_gatsby_special_1_2e7c76d997.png +0 -0
  124. package/dist/uploads/medium_wireless_headphones_1_fa75cd50c3.png +0 -0
  125. package/dist/uploads/medium_yoga_mat_premium_1_01f9a3b5fa.png +0 -0
  126. package/dist/uploads/predictive_maintenance_icons_industry_automation_600nw_2685943461_e18a8aa3b0.webp +0 -0
  127. package/dist/uploads/small_classic_cotton_tshirt_1_cd713425f6.png +0 -0
  128. package/dist/uploads/small_daviddoe_strapi_adbcd41787.jpeg +0 -0
  129. package/dist/uploads/small_ergonomic_office_chair_1_c751cffb07.png +0 -0
  130. package/dist/uploads/small_leather_travel_backpack_1_238bc1ae4d.png +0 -0
  131. package/dist/uploads/small_mechanical_keyboard_pro_1_0cd391a6ac.png +0 -0
  132. package/dist/uploads/small_smart_watch_series_5_1_cdc2511fb7.png +0 -0
  133. package/dist/uploads/small_smartphone_x_pro_1_c3f0cbd080.png +0 -0
  134. package/dist/uploads/small_the_great_gatsby_special_1_2e7c76d997.png +0 -0
  135. package/dist/uploads/small_wireless_headphones_1_fa75cd50c3.png +0 -0
  136. package/dist/uploads/small_yoga_mat_premium_1_01f9a3b5fa.png +0 -0
  137. package/dist/uploads/smart_watch_series_5_1_cdc2511fb7.png +0 -0
  138. package/dist/uploads/smartphone_x_pro_1_c3f0cbd080.png +0 -0
  139. package/dist/uploads/the_great_gatsby_special_1_2e7c76d997.png +0 -0
  140. package/dist/uploads/thumbnail_accessories_category_2a5631094b.jpeg +0 -0
  141. package/dist/uploads/thumbnail_beauty_personal_care_category_57f8a8f1e3.jpeg +0 -0
  142. package/dist/uploads/thumbnail_books_category_a9a253eada.jpeg +0 -0
  143. package/dist/uploads/thumbnail_classic_cotton_tshirt_1_cd713425f6.png +0 -0
  144. package/dist/uploads/thumbnail_clothing_category_d5c60ef07b.jpeg +0 -0
  145. package/dist/uploads/thumbnail_daviddoe_strapi_adbcd41787.jpeg +0 -0
  146. package/dist/uploads/thumbnail_electronics_category_fc3e5ef571.jpeg +0 -0
  147. package/dist/uploads/thumbnail_ergonomic_office_chair_1_c751cffb07.png +0 -0
  148. package/dist/uploads/thumbnail_home_garden_category_4f6eb3f8d6.jpeg +0 -0
  149. package/dist/uploads/thumbnail_istockphoto_1188462138_612x612_11f295b9c0.jpg +0 -0
  150. package/dist/uploads/thumbnail_istockphoto_1188462138_612x612_396fb272fd.jpg +0 -0
  151. package/dist/uploads/thumbnail_leather_travel_backpack_1_238bc1ae4d.png +0 -0
  152. package/dist/uploads/thumbnail_mechanical_keyboard_pro_1_0cd391a6ac.png +0 -0
  153. package/dist/uploads/thumbnail_predictive_maintenance_icons_industry_automation_600nw_2685943461_e18a8aa3b0.webp +0 -0
  154. package/dist/uploads/thumbnail_smart_watch_series_5_1_cdc2511fb7.png +0 -0
  155. package/dist/uploads/thumbnail_smartphone_x_pro_1_c3f0cbd080.png +0 -0
  156. package/dist/uploads/thumbnail_the_great_gatsby_special_1_2e7c76d997.png +0 -0
  157. package/dist/uploads/thumbnail_wireless_headphones_1_fa75cd50c3.png +0 -0
  158. package/dist/uploads/thumbnail_yoga_mat_premium_1_01f9a3b5fa.png +0 -0
  159. package/dist/uploads/webby-commerce.png +0 -0
  160. package/dist/uploads/wireless_headphones_1_fa75cd50c3.png +0 -0
  161. package/dist/uploads/yoga_mat_premium_1_01f9a3b5fa.png +0 -0
  162. /package/{dist → server/src}/data/demo-data.json +0 -0
@@ -0,0 +1,639 @@
1
+ 'use strict';
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+
6
+ /**
7
+ * Seed demo data from demo-data.json
8
+ */
9
+ async function seedDemoData(strapi) {
10
+ try {
11
+ strapi.log.info('[webbycommerce] Starting demo data seeding...');
12
+
13
+ // Read demo data from JSON file
14
+ // In development: server/src/utils -> server/src/data/demo-data.json
15
+ // In production: dist/server/utils -> dist/data/demo-data.json (copied during build)
16
+ let demoDataPath = path.join(__dirname, '../../data/demo-data.json');
17
+
18
+ // If not found (development mode), try the source location
19
+ if (!fs.existsSync(demoDataPath)) {
20
+ demoDataPath = path.join(__dirname, '../data/demo-data.json');
21
+ }
22
+
23
+ if (!fs.existsSync(demoDataPath)) {
24
+ throw new Error(`Demo data file not found at: ${demoDataPath}`);
25
+ }
26
+
27
+ const demoData = JSON.parse(fs.readFileSync(demoDataPath, 'utf8'));
28
+
29
+ // Track created entities for relationships
30
+ const entityMap = {
31
+ users: new Map(),
32
+ usersByIndex: [],
33
+ categories: new Map(),
34
+ tags: new Map(),
35
+ attributes: new Map(),
36
+ products: new Map(),
37
+ addresses: new Map(),
38
+ orders: new Map(),
39
+ coupons: new Map(),
40
+ shippingZones: new Map(),
41
+ carts: new Map(),
42
+ };
43
+
44
+ // Seed data in order of dependencies
45
+ await seedCategories(strapi, demoData.categories, entityMap);
46
+ await seedTags(strapi, demoData.tags, entityMap);
47
+ await seedAttributes(strapi, demoData.attributes, entityMap); // Fixed Value Slug generation
48
+ await seedCoupons(strapi, demoData.coupons, entityMap);
49
+ await seedUsers(strapi, demoData.users, entityMap);
50
+ await seedAddresses(strapi, demoData.addresses, entityMap);
51
+ await seedProducts(strapi, demoData.products, entityMap);
52
+ await seedProductVariations(strapi, demoData.product_variations, entityMap);
53
+ await seedOrders(strapi, demoData.orders, entityMap);
54
+ await seedPaymentTransactions(strapi, demoData.payment_transactions, entityMap);
55
+ await seedShippingRules(strapi, demoData.shipping_rules, entityMap);
56
+ await seedCarts(strapi, demoData.carts, entityMap);
57
+ await seedCartItems(strapi, demoData.carts, entityMap);
58
+ await seedCompares(strapi, demoData.compares, entityMap);
59
+ await seedWishlists(strapi, demoData.wishlists, entityMap);
60
+ await seedShippingZones(strapi, demoData.shipping_zones, entityMap);
61
+
62
+ strapi.log.info('[webbycommerce] Demo data seeding completed successfully!');
63
+ return { success: true, message: 'Demo data seeded successfully' };
64
+
65
+ } catch (error) {
66
+ strapi.log.error('[webbycommerce] Error seeding demo data:', error);
67
+ throw error;
68
+ }
69
+ }
70
+
71
+ async function seedCategories(strapi, categories, entityMap) {
72
+ strapi.log.info('[webbycommerce] Seeding categories...');
73
+ for (const category of categories) {
74
+ try {
75
+ const existingCategory = await strapi.entityService.findMany('plugin::webbycommerce.product-category', {
76
+ filters: { slug: category.slug }
77
+ });
78
+ if (existingCategory.length > 0) {
79
+ entityMap.categories.set(category.slug, existingCategory[0]);
80
+ continue;
81
+ }
82
+ const createdCategory = await strapi.entityService.create('plugin::webbycommerce.product-category', {
83
+ data: {
84
+ name: category.name,
85
+ slug: category.slug,
86
+ description: category.description,
87
+ publishedAt: new Date(),
88
+ }
89
+ });
90
+ entityMap.categories.set(category.slug, createdCategory);
91
+ } catch (error) {
92
+ strapi.log.error(`[webbycommerce] Error creating category ${category.name}:`, error);
93
+ }
94
+ }
95
+ }
96
+
97
+ async function seedTags(strapi, tags, entityMap) {
98
+ strapi.log.info('[webbycommerce] Seeding tags...');
99
+ for (const tag of tags) {
100
+ try {
101
+ const existingTag = await strapi.entityService.findMany('plugin::webbycommerce.product-tag', {
102
+ filters: { slug: tag.slug }
103
+ });
104
+ if (existingTag.length > 0) {
105
+ entityMap.tags.set(tag.slug, existingTag[0]);
106
+ continue;
107
+ }
108
+ const createdTag = await strapi.entityService.create('plugin::webbycommerce.product-tag', {
109
+ data: {
110
+ name: tag.name,
111
+ slug: tag.slug,
112
+ publishedAt: new Date(),
113
+ }
114
+ });
115
+ entityMap.tags.set(tag.slug, createdTag);
116
+ } catch (error) {
117
+ strapi.log.error(`[webbycommerce] Error creating tag ${tag.name}:`, error);
118
+ }
119
+ }
120
+ }
121
+
122
+ async function seedAttributes(strapi, attributes, entityMap) {
123
+ strapi.log.info('[webbycommerce] Seeding product attributes...');
124
+
125
+ for (const attribute of attributes) {
126
+ try {
127
+ // Strict slug generation from NAME
128
+ const strictSlug = attribute.name.toLowerCase().trim().replace(/\s+/g, '-');
129
+
130
+ const existingAttribute = await strapi.entityService.findMany('plugin::webbycommerce.product-attribute', {
131
+ filters: { slug: strictSlug }
132
+ });
133
+
134
+ let attributeId;
135
+
136
+ if (existingAttribute.length > 0) {
137
+ attributeId = existingAttribute[0].id;
138
+ entityMap.attributes.set(strictSlug, existingAttribute[0]);
139
+ } else {
140
+ // Create Attribute First
141
+ const createdAttribute = await strapi.entityService.create('plugin::webbycommerce.product-attribute', {
142
+ data: {
143
+ name: attribute.name,
144
+ display_name: attribute.display_name || attribute.name,
145
+ slug: strictSlug,
146
+ type: attribute.type,
147
+ sort_order: 0,
148
+ publishedAt: new Date(),
149
+ }
150
+ });
151
+ attributeId = createdAttribute.id;
152
+ entityMap.attributes.set(strictSlug, createdAttribute);
153
+ strapi.log.info(`[webbycommerce] Created attribute: ${attribute.name}`);
154
+ }
155
+
156
+ // Create Values
157
+ const attributeValues = [];
158
+ if (attribute.values && attribute.values.length > 0) {
159
+ for (const value of attribute.values) {
160
+ try {
161
+ // Generate slug for the value
162
+ const valueSlug = value.toString().toLowerCase().trim().replace(/\s+/g, '-');
163
+
164
+ const existingValue = await strapi.entityService.findMany('plugin::webbycommerce.product-attribute-value', {
165
+ filters: {
166
+ slug: valueSlug,
167
+ product_attribute: attributeId
168
+ }
169
+ });
170
+
171
+ if (existingValue.length > 0) {
172
+ attributeValues.push(existingValue[0].id);
173
+ } else {
174
+ // CRITICAL FIX: Added slug: valueSlug
175
+ const createdValue = await strapi.entityService.create('plugin::webbycommerce.product-attribute-value', {
176
+ data: {
177
+ value: value,
178
+ slug: valueSlug, // <--- THIS WAS MISSING
179
+ product_attribute: attributeId,
180
+ publishedAt: new Date(),
181
+ }
182
+ });
183
+ attributeValues.push(createdValue.id);
184
+ }
185
+ } catch (valueError) {
186
+ strapi.log.error(`[webbycommerce] Error creating value ${value} for ${attribute.name}:`, valueError);
187
+ }
188
+ }
189
+ }
190
+
191
+ // Update Attribute with Values
192
+ if (attributeValues.length > 0) {
193
+ await strapi.entityService.update('plugin::webbycommerce.product-attribute', attributeId, {
194
+ data: {
195
+ product_attribute_values: attributeValues,
196
+ }
197
+ });
198
+ }
199
+
200
+ } catch (error) {
201
+ strapi.log.error(`[webbycommerce] Error creating attribute ${attribute.name}:`, error);
202
+ }
203
+ }
204
+ }
205
+
206
+ async function seedCoupons(strapi, coupons, entityMap) {
207
+ strapi.log.info('[webbycommerce] Seeding coupons...');
208
+ for (const coupon of coupons) {
209
+ try {
210
+ const existingCoupon = await strapi.entityService.findMany('plugin::webbycommerce.coupon', {
211
+ filters: { code: coupon.code }
212
+ });
213
+ if (existingCoupon.length > 0) {
214
+ entityMap.coupons.set(coupon.code, existingCoupon[0]);
215
+ continue;
216
+ }
217
+ const createdCoupon = await strapi.entityService.create('plugin::webbycommerce.coupon', {
218
+ data: {
219
+ code: coupon.code,
220
+ type: coupon.type,
221
+ value: coupon.value,
222
+ description: coupon.description,
223
+ usage_limit: coupon.usage_limit,
224
+ is_active: coupon.is_active,
225
+ expires_at: coupon.expires_at,
226
+ publishedAt: new Date(),
227
+ }
228
+ });
229
+ entityMap.coupons.set(coupon.code, createdCoupon);
230
+ } catch (error) {
231
+ strapi.log.error(`[webbycommerce] Error creating coupon ${coupon.code}:`, error);
232
+ }
233
+ }
234
+ }
235
+
236
+ async function seedUsers(strapi, users, entityMap) {
237
+ strapi.log.info('[webbycommerce] Seeding users...');
238
+ for (const user of users) {
239
+ try {
240
+ const existingUser = await strapi.db.query('plugin::users-permissions.user').findOne({
241
+ where: { email: user.email }
242
+ });
243
+ if (existingUser) {
244
+ entityMap.users.set(user.email, existingUser);
245
+ entityMap.usersByIndex.push(existingUser);
246
+ continue;
247
+ }
248
+ const createdUser = await strapi.plugins['users-permissions'].services.user.add({
249
+ username: user.username,
250
+ email: user.email,
251
+ password: user.password,
252
+ confirmed: user.confirmed,
253
+ blocked: user.blocked,
254
+ firstName: user.firstName,
255
+ lastName: user.lastName,
256
+ });
257
+ if (!createdUser.role) {
258
+ const authenticatedRole = await strapi.db.query('plugin::users-permissions.role').findOne({
259
+ where: { type: 'authenticated' }
260
+ });
261
+ if (authenticatedRole) {
262
+ await strapi.db.query('plugin::users-permissions.user').update({
263
+ where: { id: createdUser.id },
264
+ data: { role: authenticatedRole.id }
265
+ });
266
+ }
267
+ }
268
+ entityMap.users.set(user.email, createdUser);
269
+ entityMap.usersByIndex.push(createdUser);
270
+ } catch (error) {
271
+ strapi.log.error(`[webbycommerce] Error creating user ${user.email}:`, error);
272
+ }
273
+ }
274
+ }
275
+
276
+ async function seedAddresses(strapi, addresses, entityMap) {
277
+ strapi.log.info('[webbycommerce] Seeding addresses...');
278
+ for (const address of addresses) {
279
+ try {
280
+ const user = entityMap.users.get(address.email_address);
281
+ if (!user) continue;
282
+ const existingAddress = await strapi.entityService.findMany('plugin::webbycommerce.address', {
283
+ filters: { email_address: address.email_address, type: address.type }
284
+ });
285
+ if (existingAddress.length > 0) continue;
286
+ const createdAddress = await strapi.entityService.create('plugin::webbycommerce.address', {
287
+ data: {
288
+ ...address,
289
+ user: user.id,
290
+ publishedAt: new Date(),
291
+ }
292
+ });
293
+ entityMap.addresses.set(`${address.email_address}_${address.type}`, createdAddress);
294
+ } catch (error) {
295
+ strapi.log.error(`[webbycommerce] Error creating address:`, error);
296
+ }
297
+ }
298
+ }
299
+
300
+ async function seedProducts(strapi, products, entityMap) {
301
+ strapi.log.info('[webbycommerce] Seeding products...');
302
+ for (const product of products) {
303
+ try {
304
+ const existingProduct = await strapi.entityService.findMany('plugin::webbycommerce.product', {
305
+ filters: { slug: product.slug }
306
+ });
307
+ if (existingProduct.length > 0) {
308
+ entityMap.products.set(product.slug, existingProduct[0]);
309
+ continue;
310
+ }
311
+ const categoryIds = product.categories.map(catSlug => {
312
+ const category = entityMap.categories.get(catSlug);
313
+ return category ? category.id : null;
314
+ }).filter(id => id !== null);
315
+
316
+ const tagIds = product.tags.map(tagSlug => {
317
+ const tag = entityMap.tags.get(tagSlug);
318
+ return tag ? tag.id : null;
319
+ }).filter(id => id !== null);
320
+
321
+ const createdProduct = await strapi.entityService.create('plugin::webbycommerce.product', {
322
+ data: {
323
+ name: product.name,
324
+ slug: product.slug,
325
+ description: product.description,
326
+ price: product.price,
327
+ sale_price: product.sale_price || null,
328
+ sku: product.sku,
329
+ stock_quantity: product.stock_quantity,
330
+ stock_status: product.stock_status,
331
+ weight: product.weight,
332
+ product_categories: categoryIds,
333
+ tags: tagIds,
334
+ publishedAt: new Date(),
335
+ }
336
+ });
337
+ entityMap.products.set(product.slug, createdProduct);
338
+ } catch (error) {
339
+ strapi.log.error(`[webbycommerce] Error creating product ${product.name}:`, error);
340
+ }
341
+ }
342
+ }
343
+
344
+ async function seedProductVariations(strapi, productVariations, entityMap) {
345
+ strapi.log.info('[webbycommerce] Seeding product variations...');
346
+ for (const variation of productVariations) {
347
+ try {
348
+ const existingVariation = await strapi.entityService.findMany('plugin::webbycommerce.product-variation', {
349
+ filters: { sku: variation.sku }
350
+ });
351
+ if (existingVariation.length > 0) continue;
352
+
353
+ const product = entityMap.products.get(variation.product);
354
+ if (!product) continue;
355
+
356
+ await strapi.entityService.create('plugin::webbycommerce.product-variation', {
357
+ data: {
358
+ ...variation,
359
+ product: product.id,
360
+ publishedAt: new Date(),
361
+ }
362
+ });
363
+ } catch (error) {
364
+ strapi.log.error(`[webbycommerce] Error creating product variation:`, error);
365
+ }
366
+ }
367
+ }
368
+
369
+ async function seedOrders(strapi, orders, entityMap) {
370
+ strapi.log.info('[webbycommerce] Seeding orders...');
371
+ for (const order of orders) {
372
+ try {
373
+ const existingOrder = await strapi.entityService.findMany('plugin::webbycommerce.order', {
374
+ filters: { order_number: order.order_number }
375
+ });
376
+ if (existingOrder.length > 0) {
377
+ entityMap.orders.set(order.order_number, existingOrder[0]);
378
+ continue;
379
+ }
380
+ const user = entityMap.usersByIndex[order.user];
381
+ if (!user) continue;
382
+
383
+ const billingAddress = entityMap.addresses.get(`${order.billing_address}_billing`);
384
+ const shippingAddress = entityMap.addresses.get(`${order.shipping_address}_shipping`);
385
+
386
+ const createdOrder = await strapi.entityService.create('plugin::webbycommerce.order', {
387
+ data: {
388
+ order_number: order.order_number,
389
+ status: order.status,
390
+ subtotal: order.subtotal,
391
+ tax_amount: order.tax_amount,
392
+ shipping_amount: order.shipping_amount,
393
+ total: order.total,
394
+ currency: order.currency,
395
+ payment_status: order.payment_status,
396
+ payment_method: order.payment_method,
397
+ user: user.id,
398
+ billing_address: billingAddress ? billingAddress.id : null,
399
+ shipping_address: shippingAddress ? shippingAddress.id : null,
400
+ publishedAt: new Date(),
401
+ }
402
+ });
403
+ entityMap.orders.set(order.order_number, createdOrder);
404
+ } catch (error) {
405
+ strapi.log.error(`[webbycommerce] Error creating order ${order.order_number}:`, error);
406
+ }
407
+ }
408
+ }
409
+
410
+ async function seedPaymentTransactions(strapi, transactions, entityMap) {
411
+ strapi.log.info('[webbycommerce] Seeding payment transactions...');
412
+ const ordersList = Array.from(entityMap.orders.values());
413
+
414
+ for (let i = 0; i < transactions.length; i++) {
415
+ const transaction = transactions[i];
416
+ try {
417
+ const existingTransaction = await strapi.entityService.findMany('plugin::webbycommerce.payment-transaction', {
418
+ filters: { transaction_id: transaction.transaction_id }
419
+ });
420
+
421
+ if (existingTransaction.length > 0) continue;
422
+
423
+ const order = ordersList[i];
424
+
425
+ const createdTransaction = await strapi.entityService.create('plugin::webbycommerce.payment-transaction', {
426
+ data: {
427
+ transaction_id: transaction.transaction_id,
428
+ payment_method: transaction.payment_method,
429
+ amount: transaction.amount,
430
+ currency: transaction.currency,
431
+ status: transaction.status,
432
+ processed_at: transaction.processed_at,
433
+ order: order ? order.id : null, // Link Order here
434
+ publishedAt: new Date(),
435
+ }
436
+ });
437
+ strapi.log.info(`[webbycommerce] Created payment transaction: ${transaction.transaction_id} linked to Order ${order ? order.order_number : 'None'}`);
438
+ } catch (error) {
439
+ strapi.log.error(`[webbycommerce] Error creating payment transaction ${transaction.transaction_id}:`, error);
440
+ }
441
+ }
442
+ }
443
+
444
+ async function seedShippingRules(strapi, shippingRules, entityMap) {
445
+ strapi.log.info('[webbycommerce] Seeding shipping rules...');
446
+ for (const rule of shippingRules) {
447
+ try {
448
+ const existingRule = await strapi.entityService.findMany('plugin::webbycommerce.shipping-rule', {
449
+ filters: { name: rule.name }
450
+ });
451
+ if (existingRule.length > 0) continue;
452
+ await strapi.entityService.create('plugin::webbycommerce.shipping-rule', {
453
+ data: { ...rule, publishedAt: new Date() }
454
+ });
455
+ } catch (error) {
456
+ strapi.log.error(`[webbycommerce] Error creating shipping rule:`, error);
457
+ }
458
+ }
459
+ }
460
+
461
+ async function seedCompares(strapi, compares, entityMap) {
462
+ strapi.log.info('[webbycommerce] Seeding compares...');
463
+ for (const compare of compares) {
464
+ try {
465
+ const user = entityMap.users.get(compare.userEmail);
466
+ if (!user) continue;
467
+
468
+ const productIds = compare.products.map(slug => entityMap.products.get(slug)?.id).filter(id => id);
469
+ if (productIds.length === 0) continue;
470
+
471
+ const existingCompare = await strapi.entityService.findMany('plugin::webbycommerce.compare', {
472
+ filters: { userId: String(user.id) }
473
+ });
474
+ if (existingCompare.length > 0) continue;
475
+
476
+ await strapi.entityService.create('plugin::webbycommerce.compare', {
477
+ data: {
478
+ userId: String(user.id),
479
+ userEmail: user.email,
480
+ name: compare.name,
481
+ products: productIds,
482
+ publishedAt: new Date(),
483
+ }
484
+ });
485
+ } catch (error) {
486
+ strapi.log.error(`[webbycommerce] Error creating compare:`, error);
487
+ }
488
+ }
489
+ }
490
+
491
+ async function seedWishlists(strapi, wishlists, entityMap) {
492
+ strapi.log.info('[webbycommerce] Seeding wishlists...');
493
+ for (const wishlist of wishlists) {
494
+ try {
495
+ const user = entityMap.users.get(wishlist.userEmail);
496
+ if (!user) continue;
497
+
498
+ const productIds = wishlist.products.map(slug => entityMap.products.get(slug)?.id).filter(id => id);
499
+ if (productIds.length === 0) continue;
500
+
501
+ const existingWishlist = await strapi.entityService.findMany('plugin::webbycommerce.wishlist', {
502
+ filters: { userId: String(user.id), name: wishlist.name }
503
+ });
504
+ if (existingWishlist.length > 0) continue;
505
+
506
+ await strapi.entityService.create('plugin::webbycommerce.wishlist', {
507
+ data: {
508
+ userId: String(user.id),
509
+ userEmail: user.email,
510
+ name: wishlist.name,
511
+ description: wishlist.description,
512
+ isPublic: wishlist.isPublic,
513
+ products: productIds,
514
+ publishedAt: new Date(),
515
+ }
516
+ });
517
+ } catch (error) {
518
+ strapi.log.error(`[webbycommerce] Error creating wishlist:`, error);
519
+ }
520
+ }
521
+ }
522
+
523
+ async function seedCarts(strapi, carts, entityMap) {
524
+ strapi.log.info('[webbycommerce] Seeding carts...');
525
+ for (const cart of carts) {
526
+ try {
527
+ const user = entityMap.users.get(cart.userEmail);
528
+ if (!user) continue;
529
+
530
+ const existingCart = await strapi.entityService.findMany('plugin::webbycommerce.cart', {
531
+ filters: { user: user.id }
532
+ });
533
+ if (existingCart.length > 0) {
534
+ entityMap.carts.set(user.email, existingCart[0]);
535
+ continue;
536
+ }
537
+ const createdCart = await strapi.entityService.create('plugin::webbycommerce.cart', {
538
+ data: {
539
+ user: user.id,
540
+ currency: cart.currency,
541
+ }
542
+ });
543
+ entityMap.carts.set(user.email, createdCart);
544
+ } catch (error) {
545
+ strapi.log.error(`[webbycommerce] Error creating cart:`, error);
546
+ }
547
+ }
548
+ }
549
+
550
+ async function seedCartItems(strapi, carts, entityMap) {
551
+ strapi.log.info('[webbycommerce] Seeding cart items...');
552
+ for (const cartData of carts) {
553
+ try {
554
+ const user = entityMap.users.get(cartData.userEmail);
555
+ if (!user) continue;
556
+
557
+ const cart = entityMap.carts.get(user.email);
558
+ if (!cart) continue;
559
+
560
+ for (const item of cartData.items) {
561
+ const product = entityMap.products.get(item.product);
562
+ if (!product) continue;
563
+
564
+ const existingItem = await strapi.entityService.findMany('plugin::webbycommerce.cart-item', {
565
+ filters: { cart: cart.id, product: product.id }
566
+ });
567
+ if (existingItem.length > 0) continue;
568
+
569
+ const finalPrice = (product.sale_price && product.sale_price < product.price) ? product.sale_price : product.price;
570
+
571
+ await strapi.entityService.create('plugin::webbycommerce.cart-item', {
572
+ data: {
573
+ cart: cart.id,
574
+ product: product.id,
575
+ quantity: item.quantity,
576
+ unit_price: finalPrice,
577
+ total_price: finalPrice * item.quantity,
578
+ user: user.id,
579
+ }
580
+ });
581
+ }
582
+ } catch (error) {
583
+ strapi.log.error(`[webbycommerce] Error creating cart items:`, error);
584
+ }
585
+ }
586
+ }
587
+
588
+ async function seedShippingZones(strapi, shippingZones, entityMap) {
589
+ strapi.log.info('[webbycommerce] Seeding shipping zones...');
590
+ for (const zone of shippingZones) {
591
+ try {
592
+ const existingZone = await strapi.entityService.findMany('plugin::webbycommerce.shipping-zone', {
593
+ filters: { name: zone.name }
594
+ });
595
+ if (existingZone.length > 0) continue;
596
+
597
+ const shippingMethods = [];
598
+ for (const method of zone.methods) {
599
+ const createdMethod = await strapi.entityService.create('plugin::webbycommerce.shipping-method', {
600
+ data: {
601
+ ...method,
602
+ is_active: true,
603
+ publishedAt: new Date(),
604
+ }
605
+ });
606
+
607
+ if (method.rates) {
608
+ for (const rate of method.rates) {
609
+ await strapi.entityService.create('plugin::webbycommerce.shipping-rate', {
610
+ data: {
611
+ ...rate,
612
+ shipping_method: createdMethod.id,
613
+ publishedAt: new Date(),
614
+ }
615
+ });
616
+ }
617
+ }
618
+ shippingMethods.push(createdMethod.id);
619
+ }
620
+
621
+ await strapi.entityService.create('plugin::webbycommerce.shipping-zone', {
622
+ data: {
623
+ name: zone.name,
624
+ location: [zone.location],
625
+ shippingMethods: shippingMethods,
626
+ is_active: true,
627
+ sort_order: 0,
628
+ }
629
+ });
630
+ } catch (error) {
631
+ strapi.log.error(`[webbycommerce] Error creating shipping zone:`, error);
632
+ }
633
+ }
634
+ }
635
+
636
+
637
+ module.exports = {
638
+ seedDemoData,
639
+ };