Current section

7 Versions

Jump to

Compare versions

12 files changed
+308 additions
-18 deletions
  @@ -11,12 +11,19 @@
11 11 <<"lib/ex_catalog/mix/tasks/install.ex">>,<<"lib/ex_catalog/util.ex">>,
12 12 <<"lib/ex_catalog/repo.ex">>,<<"lib/ex_catalog/config.ex">>,
13 13 <<"lib/ex_catalog/schema">>,<<"lib/ex_catalog/schema/category.ex">>,
14 + <<"lib/ex_catalog/schema/manufacturer">>,
15 + <<"lib/ex_catalog/schema/manufacturer/slug.ex">>,
14 16 <<"lib/ex_catalog/schema/video.ex">>,
15 17 <<"lib/ex_catalog/schema/currency.ex">>,
16 18 <<"lib/ex_catalog/schema/product.ex">>,<<"lib/ex_catalog/schema/meta.ex">>,
17 - <<"lib/ex_catalog/schema/image.ex">>,<<"lib/ex_catalog/schema/product">>,
19 + <<"lib/ex_catalog/schema/image.ex">>,<<"lib/ex_catalog/schema/video">>,
20 + <<"lib/ex_catalog/schema/video/slug.ex">>,
21 + <<"lib/ex_catalog/schema/product">>,
18 22 <<"lib/ex_catalog/schema/product/category.ex">>,
23 + <<"lib/ex_catalog/schema/product/slug.ex">>,
19 24 <<"lib/ex_catalog/schema/product/variation.ex">>,
25 + <<"lib/ex_catalog/schema/product/variation.slug.ex">>,
26 + <<"lib/ex_catalog/schema/manufacturer.ex">>,
20 27 <<"lib/ex_catalog/schema/category">>,
21 28 <<"lib/ex_catalog/schema/category/slug.ex">>,
22 29 <<"lib/ex_catalog/exceptions.ex">>,<<"lib/ex_catalog/autoslug.ex">>,
  @@ -78,4 +85,4 @@
78 85 {<<"optional">>,true},
79 86 {<<"repository">>,<<"hexpm">>},
80 87 {<<"requirement">>,<<"~> 1.7">>}]]}.
81 - {<<"version">>,<<"1.5.3">>}.
88 + {<<"version">>,<<"1.5.4">>}.
  @@ -6,6 +6,7 @@ defmodule ExCatalog do
6 6
7 7 alias ExCatalog.Category
8 8 alias ExCatalog.Product
9 + alias ExCatalog.Manufacturer
9 10
10 11 @doc """
11 12 List version.
  @@ -182,15 +183,13 @@ defmodule ExCatalog do
182 183 reply
183 184
184 185 _ ->
185 - {p, metadata} = reply
186 -
187 186 modified =
188 - Enum.map(p, fn x ->
187 + Enum.map(reply.entries, fn x ->
189 188 {:ok, price} = ExCatalog.Currencies.convert(x.price, currency)
190 189 %{x | price: price}
191 190 end)
192 191
193 - {modified, metadata}
192 + {modified, reply.metadata}
194 193 end
195 194 end
196 195
  @@ -267,12 +266,13 @@ defmodule ExCatalog do
267 266 order = Keyword.get(opts, :order) || :desc
268 267 by = Keyword.get(opts, :order_by) || :updated_at
269 268 order_by = [{order, by}]
269 + origins = Keyword.get(opts, :origins) || []
270 270
271 271 query =
272 272 case(deleted) do
273 273 false ->
274 - from(ExCatalog.Product,
275 - where: [category_id: ^category.id],
274 + from(p in ExCatalog.Product,
275 + where: p.category_id == ^category.id and p.origin not in ^origins,
276 276 order_by: ^order_by,
277 277 preload: [:variations],
278 278 preload: [:categories],
  @@ -283,8 +283,8 @@ defmodule ExCatalog do
283 283 )
284 284
285 285 true ->
286 - from(ExCatalog.Product,
287 - where: [category_id: ^category.id],
286 + from(p in ExCatalog.Product,
287 + where: p.category_id == ^category.id and p.origin not in ^origins,
288 288 preload: [:variations],
289 289 preload: [:categories],
290 290 preload: [:metas],
  @@ -329,18 +329,205 @@ defmodule ExCatalog do
329 329 reply
330 330
331 331 _ ->
332 - {data, meta} = reply
333 -
334 332 modified =
335 - Enum.map(data, fn x ->
333 + Enum.map(reply.entries, fn x ->
336 334 {:ok, price} = ExCatalog.Currencies.convert(x.price, currency)
337 335 %{x | price: price}
338 336 end)
339 337
340 - {modified, meta}
338 + {modified, reply.metadata}
341 339 end
342 340 end
343 341
342 + ###
343 + @doc """
344 + List product with preloads by category and optional currency conversion.
345 +
346 + ## Examples
347 +
348 + iex> ExCatalog.products_by_category("test_category", "2242", :USD, false, order_by: :sku)
349 +
350 +
351 + """
352 + def products_by_country(slug, limit \\ 25, currency \\ :USD, deleted \\ false, opts \\ [])
353 + when is_list(slug) do
354 + products_by_country(slug, limit, nil, nil, currency, deleted, opts)
355 + end
356 +
357 + def products_by_country(slug, limit, metadata, cursor, currency, deleted, opts) do
358 + import Ecto.Query
359 + import Ecto.SoftDelete.Query
360 +
361 + order = Keyword.get(opts, :order) || :desc
362 + by = Keyword.get(opts, :order_by) || :updated_at
363 + order_by = [{order, by}]
364 +
365 + query =
366 + case(deleted) do
367 + false ->
368 + from(p in ExCatalog.Product,
369 + where: p.slug not in ^slug,
370 + order_by: ^order_by,
371 + preload: [:variations],
372 + preload: [:categories],
373 + preload: [:metas],
374 + preload: [:primary_image],
375 + preload: [:images],
376 + preload: [:videos]
377 + )
378 +
379 + true ->
380 + from(p in ExCatalog.Product,
381 + where: p.slug not in ^slug,
382 + preload: [:variations],
383 + preload: [:categories],
384 + preload: [:metas],
385 + preload: [:primary_image],
386 + preload: [:images],
387 + preload: [:videos]
388 + )
389 + |> with_undeleted
390 + end
391 +
392 + reply =
393 + case cursor do
394 + :before ->
395 + @repo.paginate(
396 + query,
397 + before: metadata.before,
398 + include_total_count: true,
399 + cursor_fields: [:inserted_at, :id],
400 + limit: limit
401 + )
402 +
403 + :after ->
404 + @repo.paginate(
405 + query,
406 + after: metadata.after,
407 + include_total_count: true,
408 + cursor_fields: [:inserted_at, :id],
409 + limit: limit
410 + )
411 +
412 + _ ->
413 + @repo.paginate(
414 + query,
415 + include_total_count: true,
416 + cursor_fields: [:inserted_at, :id],
417 + limit: limit
418 + )
419 + end
420 +
421 + case currency do
422 + nil ->
423 + reply
424 +
425 + _ ->
426 + modified =
427 + Enum.map(reply.entries, fn x ->
428 + {:ok, price} = ExCatalog.Currencies.convert(x.price, currency)
429 + %{x | price: price}
430 + end)
431 +
432 + {modified, reply.metadata}
433 + end
434 + end
435 +
436 + @doc """
437 + List product with preloads by category and optional currency conversion.
438 +
439 + ## Examples
440 +
441 + iex> ExCatalog.products_by_category("test_category", "2242", :USD, false, order_by: :sku)
442 +
443 +
444 + """
445 + def products_by_manufacturer(slug, limit \\ 25, currency \\ :USD, deleted \\ false, opts \\ []) do
446 + products_by_manufacturer(slug, limit, nil, nil, currency, deleted, opts)
447 + end
448 +
449 + def products_by_manufacturer(slug, limit, metadata, cursor, currency, deleted, opts) do
450 + manufacturer = @repo.get_by(%Manufacturer{}, slug: slug)
451 +
452 + import Ecto.Query
453 + import Ecto.SoftDelete.Query
454 +
455 + order = Keyword.get(opts, :order) || :desc
456 + by = Keyword.get(opts, :order_by) || :updated_at
457 + order_by = [{order, by}]
458 +
459 + query =
460 + case(deleted) do
461 + false ->
462 + from(ExCatalog.Product,
463 + where: [manufacturer: ^manufacturer],
464 + order_by: ^order_by,
465 + preload: [:variations],
466 + preload: [:categories],
467 + preload: [:metas],
468 + preload: [:primary_image],
469 + preload: [:images],
470 + preload: [:videos]
471 + )
472 +
473 + true ->
474 + from(ExCatalog.Product,
475 + where: [origin: ^slug],
476 + preload: [:variations],
477 + preload: [:categories],
478 + preload: [:metas],
479 + preload: [:primary_image],
480 + preload: [:images],
481 + preload: [:videos]
482 + )
483 + |> with_undeleted
484 + end
485 +
486 + reply =
487 + case cursor do
488 + :before ->
489 + @repo.paginate(
490 + query,
491 + before: metadata.before,
492 + include_total_count: true,
493 + cursor_fields: [:inserted_at, :id],
494 + limit: limit
495 + )
496 +
497 + :after ->
498 + @repo.paginate(
499 + query,
500 + after: metadata.after,
501 + include_total_count: true,
502 + cursor_fields: [:inserted_at, :id],
503 + limit: limit
504 + )
505 +
506 + _ ->
507 + @repo.paginate(
508 + query,
509 + include_total_count: true,
510 + cursor_fields: [:inserted_at, :id],
511 + limit: limit
512 + )
513 + end
514 +
515 + case currency do
516 + nil ->
517 + reply
518 +
519 + _ ->
520 + modified =
521 + Enum.map(reply.entries, fn x ->
522 + {:ok, price} = ExCatalog.Currencies.convert(x.price, currency)
523 + %{x | price: price}
524 + end)
525 +
526 + {modified, reply.metadata}
527 + end
528 + end
529 +
530 + ###
344 531 @doc """
345 532 Change the status active or disabled, this controls which products the user can see, (by default only the active products are displayed)
  @@ -0,0 +1,46 @@
1 + defmodule ExCatalog.Manufacturer do
2 + use ExCatalog.Schema
3 + import Ecto.Changeset
4 + use EctoAutoslugField.Slug, from: :title, to: :slug
5 + use ExCatalog.AutoSlug
6 +
7 + alias ExCatalog.Manufacturer.TitleSlug
8 +
9 + @repo ExCatalog.Config.repo()
10 +
11 + schema "catalog_manufacturers" do
12 + field(:title, :string)
13 + field(:description, :string)
14 +
15 + field(:slug, TitleSlug.Type)
16 + end
17 +
18 + @doc false
19 + def changeset(schema, attrs) do
20 + schema
21 + |> cast(attrs, [:title, :description])
22 + |> validate_required([:title])
23 + end
24 +
25 + @doc false
26 + def changeset_assoc(schema, attrs) do
27 + schema
28 + |> changeset(attrs)
29 + end
30 +
31 + @doc """
32 + Create a New Manufacturer
33 +
34 + ## Examples
35 +
36 + iex> manufacturer = %{title: "test Manufacturer", description: "test Manufacturers"}
37 + iex> ExCatalog.Manufacturers.new(manufacturer)
38 +
39 +
40 + """
41 + def new(params \\ %{}, struct \\ %ExCatalog.Product{}) do
42 + struct
43 + |> changeset(params)
44 + |> @repo.insert()
45 + end
46 + end
  @@ -0,0 +1,4 @@
1 + defmodule ExCatalog.Manufacturer.TitleSlug do
2 + @moduledoc false
3 + use EctoAutoslugField.Slug, from: :title, to: :slug
4 + end
  @@ -2,6 +2,10 @@ defmodule ExCatalog.Product do
2 2 use ExCatalog.Schema
3 3 import Ecto.Changeset
4 4 import Ecto.SoftDelete.Schema
5 + use EctoAutoslugField.Slug, from: :title, to: :slug
6 + use ExCatalog.AutoSlug
7 +
8 + alias ExCatalog.Product.TitleSlug
5 9
6 10 @repo ExCatalog.Config.repo()
7 11
  @@ -11,10 +15,16 @@ defmodule ExCatalog.Product do
11 15 field(:title, :string)
12 16 field(:sub_title, :string)
13 17 field(:description, :string)
18 + field(:model, :string)
19 + field(:origin, :string)
14 20 field(:owner_id, @foreign_key_type)
15 21
22 + field(:slug, TitleSlug.Type)
23 +
16 24 belongs_to(:primary_image, ExCatalog.Image)
17 25
26 + belongs_to(:manufacturer, ExCatalog.Manufacturer)
27 +
18 28 many_to_many(:variations, ExCatalog.Product,
19 29 join_through: ExCatalog.Product.Variation,
20 30 on_replace: :delete
  @@ -35,7 +45,18 @@ defmodule ExCatalog.Product do
35 45 @doc false
36 46 def changeset(schema, attrs) do
37 47 schema
38 - |> cast(attrs, [:sku, :price, :title, :sub_title, :description, :primary_image_id, :owner_id])
48 + |> cast(attrs, [
49 + :sku,
50 + :price,
51 + :title,
52 + :model,
53 + :sub_title,
54 + :description,
55 + :primary_image_id,
56 + :owner_id,
57 + :origin,
58 + :manufacturer
59 + ])
39 60 |> validate_required([:sku, :price, :title, :sub_title, :description])
40 61 end
41 62
  @@ -46,6 +67,7 @@ defmodule ExCatalog.Product do
46 67 categories = attrs[:categories] || []
47 68 metas = attrs[:metas] || []
48 69 variations = attrs[:variations] || []
70 + manufacturer = attrs[:manufacturer] || []
49 71
50 72 schema
51 73 |> changeset(attrs)
  @@ -54,6 +76,7 @@ defmodule ExCatalog.Product do
54 76 |> cast_assoc(:categories, categories)
55 77 |> cast_assoc(:metas, metas)
56 78 |> cast_assoc(:variations, variations)
79 + |> cast_assoc(:manufacturer, manufacturer)
57 80 end
58 81
59 82 @doc """
Loading more files…