diff --git a/README.md b/README.md index ab5042f..bd8dca1 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,401 @@ To start your Phoenix server: * Install Node.js dependencies with `npm install` inside the `assets` directory * Start Phoenix endpoint with `mix phx.server` -Now you can visit [`localhost:4000`](http://localhost:4000) from your browser. +- [Businesses](#businesses) + - [Get All Business](#http://localhost:4001/api/businesses-get) + - [Get a Business](#http://localhost:4001/api/businessesid-get) + - [Add a Business](#http://localhost:4001/api/businesses-post) + - [Update a Business](#http://localhost:4001/api/businessesid-put) + - [Delete a Business](#http://localhost:4001/api/businessesid-delete) +- [Collaborators](#collaborators) + - [Get All Collaborators](#http://localhost:4001/api/collaborators-get) + - [Get one Collaborator](#http://localhost:4001/api/collaboratorsid-get) + - [Add a Collaborator](#http://localhost:4001/api/collaborators-post) + - [Update a Collaborator](#http://localhost:4001/api/collaboratorsid-put) + - [Delete a Collaborator](#http://localhost:4001/api/collaboratorsid-delete) + - [Get All Colaborators From a Business and a Year](#http://localhost:4001/api/get_collaborators_businesess_by_yearidyear-get) + +### Businesses + +#### http://localhost:4001/api/businesses (GET) + +Get All Businesses Registered. + +**REQUEST** +Headers: `Content-Type: application/json` + +**RESPONSE** +``` +{ + "data": [ + { + "collaborators": { + "data": [ + { + "email": "some@gmail.com", + "id": 1, + "lastname": "Doe", + "name": "Jhon" + } + ] + }, + "date": "2020-07-26 00:39:09", + "description": "Short description ...", + "id": 1, + "name": "Company 1", + "tag": "IT, Software", + "year": 2000 + }, + { + "collaborators": { + "data": [ + { + "email": "some@gmail.com", + "id": 2, + "lastname": "Dow", + "name": "Jane" + } + ] + }, + "date": "2020-07-26 00:39:09", + "description": "Short description ...", + "id": 2, + "name": "Company 2", + "tag": "Marketing", + "year": 2000 + }, + { + "collaborators": { + "data": [ + { + "email": "some@gmail.com", + "id": 3, + "lastname": "Other", + "name": "Some" + } + ] + }, + "date": "2020-07-26 00:39:09", + "description": "Short description ...", + "id": 3, + "name": "Company 3", + "tag": "Accounting", + "year": 2000 + } + ] +} +``` + +--- +#### http://localhost:4001/api/businesses/:id (GET) + +Get one Business Registered. + +**REQUEST** +Headers: `Content-Type: application/json` +Path Variables: `id` = `1` + +**RESPONSE** +``` +{ + "data": { + "collaborators": { + "data": [ + { + "email": "some@gmail.com", + "id": 1, + "lastname": "Doe", + "name": "Jhon" + } + ] + }, + "date": "2020-07-26 00:39:09", + "description": "Short description ...", + "id": 1, + "name": "Name Updated", + "tag": "IT, Software", + "year": 2000 + } +} +``` + +--- +#### http://localhost:4001/api/businesses (POST) + +Store a new Business. + +**REQUEST** +Headers: `Content-Type: application/json` +``` +{ + "business": + { + "name": "Yet another new company", + "description": "Another new short description!", + "tag": "A Tag", + "year": "2000" + } +} +``` +**RESPONSE** +``` +{ + "date": "2020-07-26 00:51:36", + "description": "Another new short description!", + "id": 4, + "name": "Yet another new company", + "tag": "A Tag", + "year": 2000 +} +``` + +--- +#### http://localhost:4001/api/businesses/:id (PUT) + +Update a Business + +**REQUEST** +Headers: `Content-Type: application/json` +Path Variables: `id` = `1` +``` +{ + "business": + { + "name": "Name Updated" + } +} +``` +**RESPONSE** +``` +{ + "data": { + "collaborators": { + "data": [ + { + "email": "some@gmail.com", + "id": 1, + "lastname": "Doe", + "name": "Jhon" + } + ] + }, + "date": "2020-07-26 00:39:09", + "description": "Short description ...", + "id": 1, + "name": "Name Updated", + "tag": "IT, Software", + "year": 2000 + } +} +``` + +--- +#### http://localhost:4001/api/businesses/:id (DELETE) + +Delete one Business. + +**REQUEST** +Headers: `x-access-token` +Path Variables: id = 2 + +**RESPONSE** +``` + If ok no Response + +``` + +--- +### Collaborators +#### http://localhost:4001/api/collaborators (GET) + +Get All Collaborators Registered. + +**REQUEST** +Headers: `Content-Type: application/json` + +**RESPONSE** +``` +{ + "data": [ + { + "business": { + "description": "Short description ...", + "id": 1, + "name": "Name Updated", + "tag": "IT, Software", + "year": 2000 + }, + "email": "some@gmail.com", + "id": 1, + "lastname": "Doe", + "name": "Jhon" + }, + { + "business": { + "description": "Short description ...", + "id": 2, + "name": "Company 2", + "tag": "Marketing", + "year": 2000 + }, + "email": "some@gmail.com", + "id": 2, + "lastname": "Dow", + "name": "Jane" + }, + { + "business": { + "description": "Short description ...", + "id": 3, + "name": "Company 3", + "tag": "Accounting", + "year": 2000 + }, + "email": "some@gmail.com", + "id": 3, + "lastname": "Other", + "name": "Some" + } + ] +} +``` + +--- +#### http://localhost:4001/api/collaborators/:id (GET) + +Get one Collaborator Registered. + +**REQUEST** +Headers: `Content-Type: application/json` +Path Variables: `id` = `1` + +**RESPONSE** +``` +{ + "data": { + "business": { + "description": "Short description ...", + "id": 1, + "name": "Name Updated", + "tag": "IT, Software", + "year": 2000 + }, + "email": "some@gmail.com", + "id": 1, + "lastname": "Doe", + "name": "Jhon" + } +} +``` + +--- +#### http://localhost:4001/api/collaborators (POST) + +Store a new Collaborator. + +**REQUEST** +Headers: `Content-Type: application/json` +``` +{ + "colaborator": + { + "name": "Some Other Collaborator Name", + "lastname": "Some Other Collaborator LastName", + "email": "some_email@some.com", + "business_id": 2 + } +} +``` +**RESPONSE** +``` +{ + "email": "some_email@some.com", + "id": 4, + "lastname": "Some Other Collaborator LastName", + "name": "Some Other Collaborator Name" +} +``` + +--- +#### http://localhost:4001/api/collaborators/:id (PUT) + +Update a Collaborator + +**REQUEST** +Headers: `Content-Type: application/json` +Path Variables: `id` = `1` +``` +{ + "colaborator": + { + "name": "Name Updated" + } +} +``` +**RESPONSE** +``` +{ + "data": { + "business": { + "description": "Short description ...", + "id": 1, + "name": "Name Updated", + "tag": "IT, Software", + "year": 2000 + }, + "email": "some@gmail.com", + "id": 1, + "lastname": "Doe", + "name": "Name Updated" + } +} +``` + +--- +#### http://localhost:4001/api/collaborators/:id (DELETE) + +Delete one Business. + +**REQUEST** +Headers: `x-access-token` +Path Variables: id = 2 + +**RESPONSE** +``` + If ok no Response +``` + +--- + +#### http://localhost:4001/api/get_collaborators_businesess_by_year/:id/:year (GET) + +Get All Collaborators that belongs to a specific Business in a specific Year . + +**REQUEST** +Headers: `Content-Type: application/json` +Path Variables: id = 1, year = 2000 + +**RESPONSE** +``` +{ + "data": [ + { + "email": "some@gmail.com", + "id": 1, + "lastname": "Doe", + "name": "Jhon" + } + ] +} +``` + +--- + + + + + -Ready to run in production? Please [check our deployment guides](https://hexdocs.pm/phoenix/deployment.html). ## Learn more diff --git a/config/dev.exs b/config/dev.exs index 7b78fb5..8af2cdc 100644 --- a/config/dev.exs +++ b/config/dev.exs @@ -16,7 +16,7 @@ config :busi_api, BusiApi.Repo, # watchers to your application. For example, we use it # with webpack to recompile .js and .css sources. config :busi_api, BusiApiWeb.Endpoint, - http: [port: 4000], + http: [port: 4001], debug_errors: true, code_reloader: true, check_origin: false, diff --git a/lib/busi_api/directory.ex b/lib/busi_api/directory.ex index 3ef704d..61cd788 100644 --- a/lib/busi_api/directory.ex +++ b/lib/busi_api/directory.ex @@ -17,9 +17,15 @@ defmodule BusiApi.Directory do [%Business{}, ...] """ - def list_businesses do - Repo.all(Business) - end + # def list_businesses do + # query = from b in Business, + # join: c in assoc(b, :colaborators), + # preload: [colaborators: c] + # Repo.all(query) + # end + + def list_businesses, do: Repo.all(Business) |> Repo.preload([:colaborators]) + @doc """ Gets a single business. @@ -35,7 +41,7 @@ defmodule BusiApi.Directory do ** (Ecto.NoResultsError) """ - def get_business!(id), do: Repo.get!(Business, id) + def get_business!(id), do: Repo.get!(Business, id) |> Repo.preload([:colaborators]) @doc """ Creates a business. @@ -101,4 +107,41 @@ defmodule BusiApi.Directory do def change_business(%Business{} = business, attrs \\ %{}) do Business.changeset(business, attrs) end + + @spec get_businesess_collaborators(any, any) :: any + def get_businesess_collaborators(id,year) do + query = from b in Business, + where: b.id == ^id and b.year == ^year, + join: c in Colaborator, + on: c.business_id == b.id, + select: c + Repo.all(query) + end + + alias BusiApi.Directory.Colaborator + + def list_collaborators, do: Repo.all(Colaborator) |> Repo.preload([:business]) + + def get_collaborator!(id), do: Repo.get!(Colaborator, id) |> Repo.preload([:business]) + + def create_collaborator(attrs \\ %{}) do + %Colaborator{} + |> Colaborator.changeset(attrs) + |> Repo.insert() + end + + def update_collaborator(%Colaborator{} = colaborator, attrs) do + colaborator + |> Colaborator.changeset(attrs) + |> Repo.update() + end + + def delete_collaborator(%Colaborator{} = colaborator) do + Repo.delete(colaborator) + end + + def change_collaborator(%Colaborator{} = colaborator, attrs \\ %{}) do + Colaborator.changeset(colaborator, attrs) + end + end diff --git a/lib/busi_api/directory/business.ex b/lib/busi_api/directory/business.ex index b2c0032..5182cef 100644 --- a/lib/busi_api/directory/business.ex +++ b/lib/busi_api/directory/business.ex @@ -4,16 +4,16 @@ defmodule BusiApi.Directory.Business do schema "businesses" do field :description, :string - field :name, :string - field :tag, :string - + field :name, :string + field :tag, :string + field :year, :integer + has_many :colaborators, BusiApi.Directory.Colaborator timestamps() end - @doc false def changeset(business, attrs) do business - |> cast(attrs, [:name, :description, :tag]) - |> validate_required([:name, :description, :tag]) + |> cast(attrs, [:name, :description, :tag, :year]) + |> validate_required([:name, :description, :tag, :year]) end end diff --git a/lib/busi_api/directory/colaborator.ex b/lib/busi_api/directory/colaborator.ex new file mode 100644 index 0000000..c1604a5 --- /dev/null +++ b/lib/busi_api/directory/colaborator.ex @@ -0,0 +1,19 @@ +defmodule BusiApi.Directory.Colaborator do + use Ecto.Schema + import Ecto.Changeset + + schema "colaborators" do + field :email, :string + field :lastname, :string + field :name, :string + belongs_to :business, BusiApi.Directory.Business + timestamps() + end + + def changeset(colaborator, attrs) do + colaborator + |> cast(attrs, [:name, :lastname, :email, :business_id]) + |> validate_required([:name, :lastname, :email, :business_id]) + |> assoc_constraint(:business) + end +end diff --git a/lib/busi_api_web/controllers/business_controller.ex b/lib/busi_api_web/controllers/business_controller.ex index 759b29d..63a1535 100644 --- a/lib/busi_api_web/controllers/business_controller.ex +++ b/lib/busi_api_web/controllers/business_controller.ex @@ -1,13 +1,14 @@ defmodule BusiApiWeb.BusinessController do use BusiApiWeb, :controller - alias BusiApi.Directory alias BusiApi.Directory.Business + #alias BusiApi.Directory.Colaborator action_fallback BusiApiWeb.FallbackController def index(conn, _params) do businesses = Directory.list_businesses() + |>IO.inspect() render(conn, "index.json", businesses: businesses) end @@ -16,7 +17,7 @@ defmodule BusiApiWeb.BusinessController do conn |> put_status(:created) |> put_resp_header("location", Routes.business_path(conn, :show, business)) - |> render("show.json", business: business) + |> render("business.json", business: business) end end diff --git a/lib/busi_api_web/controllers/colaborator_controller.ex b/lib/busi_api_web/controllers/colaborator_controller.ex new file mode 100644 index 0000000..792d923 --- /dev/null +++ b/lib/busi_api_web/controllers/colaborator_controller.ex @@ -0,0 +1,49 @@ +defmodule BusiApiWeb.ColaboratorController do + use BusiApiWeb, :controller + alias BusiApi.Directory + alias BusiApi.Directory.Colaborator + + action_fallback BusiApiWeb.FallbackController + + def index(conn, _params) do + colaborators = Directory.list_collaborators() + |>IO.inspect() + render(conn, "index.json", colaborators: colaborators) + end + + def create(conn, %{"colaborator" => colaborator_params}) do + with {:ok, %Colaborator{} = colaborator} <- Directory.create_collaborator(colaborator_params) do + conn + |> put_status(:created) + |> put_resp_header("location", Routes.colaborator_path(conn, :show, colaborator)) + |> render("colaborator.json", colaborator: colaborator) + end + end + + def show(conn, %{"id" => id}) do + colaborator = Directory.get_collaborator!(id) + render(conn, "show.json", colaborator: colaborator) + end + + def update(conn, %{"id" => id, "colaborator" => colaborator_params}) do + colaborator = Directory.get_collaborator!(id) + with {:ok, %Colaborator{} = colaborator} <- Directory.update_collaborator(colaborator, colaborator_params) do + render(conn, "show.json", colaborator: colaborator) + end + end + + def delete(conn, %{"id" => id}) do + colaborator = Directory.get_collaborator!(id) + with {:ok, %Colaborator{}} <- Directory.delete_collaborator(colaborator) do + send_resp(conn, :no_content, "") + end + end + + def get_businesess_collaborators(conn, %{"id" => id, "year" => year}) do + colaborators = Directory.get_businesess_collaborators(id, year) + |>IO.inspect() + render(conn, "index.json", colaborators: colaborators) + end + + + end diff --git a/lib/busi_api_web/router.ex b/lib/busi_api_web/router.ex index 6b9a703..17a4a81 100644 --- a/lib/busi_api_web/router.ex +++ b/lib/busi_api_web/router.ex @@ -21,8 +21,11 @@ defmodule BusiApiWeb.Router do scope "/api", BusiApiWeb do pipe_through :api resources "/businesses", BusinessController, except: [:new, :edit] + resources "/collaborators", ColaboratorController, except: [:new, :edit] + get "/get_collaborators_businesess_by_year/:id/:year", ColaboratorController, :get_businesess_collaborators end + # Enables LiveDashboard only for development # # If you want to use the LiveDashboard in production, you should put diff --git a/lib/busi_api_web/views/business_view.ex b/lib/busi_api_web/views/business_view.ex index 1bf0bd9..da1c70b 100644 --- a/lib/busi_api_web/views/business_view.ex +++ b/lib/busi_api_web/views/business_view.ex @@ -1,22 +1,38 @@ defmodule BusiApiWeb.BusinessView do use BusiApiWeb, :view alias BusiApiWeb.BusinessView + alias BusiApiWeb.ColaboratorView def render("index.json", %{businesses: businesses}) do - %{data: render_many(businesses, BusinessView, "business.json")} + %{data: render_many(businesses, BusinessView, "business_assoc.json")} end def render("show.json", %{business: business}) do - %{data: render_one(business, BusinessView, "business.json")} + %{data: render_one(business, BusinessView, "business_assoc.json")} end + def render("business_assoc.json", %{business: business}) do + %{ + id: business.id, + name: business.name, + description: business.description, + tag: business.tag, + date: NaiveDateTime.to_string(business.inserted_at), + year: business.year, + collaborators: + %{ + data: render_many(business.colaborators, ColaboratorView, "colaborator.json") + } + } + end def render("business.json", %{business: business}) do %{ id: business.id, name: business.name, description: business.description, tag: business.tag, - date: NaiveDateTime.to_string(business.inserted_at) + date: NaiveDateTime.to_string(business.inserted_at), + year: business.year } end end diff --git a/lib/busi_api_web/views/colaborator_view.ex b/lib/busi_api_web/views/colaborator_view.ex new file mode 100644 index 0000000..8c9bd46 --- /dev/null +++ b/lib/busi_api_web/views/colaborator_view.ex @@ -0,0 +1,37 @@ +defmodule BusiApiWeb.ColaboratorView do + use BusiApiWeb, :view + alias BusiApiWeb.ColaboratorView + + def render("index.json", %{colaborators: colaborators}) do + %{data: render_many(colaborators, ColaboratorView, "colaborator_assoc.json")} + end + + def render("show.json", %{colaborator: colaborator}) do + %{data: render_one(colaborator, ColaboratorView, "colaborator_assoc.json")} + end + + def render("colaborator_assoc.json", %{colaborator: colaborator}) do + %{ + id: colaborator.id, + name: colaborator.name, + lastname: colaborator.lastname, + email: colaborator.email, + business: + %{ + id: colaborator.business.id, + name: colaborator.business.name, + description: colaborator.business.description, + tag: colaborator.business.tag, + year: colaborator.business.year + } + } + end + def render("colaborator.json", %{colaborator: colaborator}) do + %{ + id: colaborator.id, + name: colaborator.name, + lastname: colaborator.lastname, + email: colaborator.email + } + end + end \ No newline at end of file diff --git a/priv/repo/migrations/20200723184303_add_year_to_businesses.exs b/priv/repo/migrations/20200723184303_add_year_to_businesses.exs new file mode 100644 index 0000000..d7203d0 --- /dev/null +++ b/priv/repo/migrations/20200723184303_add_year_to_businesses.exs @@ -0,0 +1,9 @@ +defmodule BusiApi.Repo.Migrations.AddYearToBusinesses do + use Ecto.Migration + + def change do + alter table(:businesses) do + add :year, :integer + end + end +end diff --git a/priv/repo/migrations/20200723192526_create_colaborators.exs b/priv/repo/migrations/20200723192526_create_colaborators.exs new file mode 100644 index 0000000..ba6c861 --- /dev/null +++ b/priv/repo/migrations/20200723192526_create_colaborators.exs @@ -0,0 +1,14 @@ +defmodule BusiApi.Repo.Migrations.CreateColaborators do + use Ecto.Migration + + def change do + create table(:colaborators) do + add :name, :string + add :lastname, :string + add :email, :string + add :business_id, references(:businesses) + timestamps() + end + + end +end diff --git a/priv/repo/seeds.exs b/priv/repo/seeds.exs index 8343511..f96dca8 100644 --- a/priv/repo/seeds.exs +++ b/priv/repo/seeds.exs @@ -11,6 +11,12 @@ # and so on) as they will fail if something goes wrong. alias BusiApi.Repo alias BusiApi.Directory.Business -Repo.insert! %Business{name: "Company 1", description: "Short description ...", tag: "IT, Software"} -Repo.insert! %Business{name: "Company 2", description: "Short description ...", tag: "Marketing"} -Repo.insert! %Business{name: "Company 3", description: "Short description ...", tag: "Accounting"} \ No newline at end of file + +Repo.insert! %Business{name: "Company 1", description: "Short description ...", tag: "IT, Software", year: 2000 } +Repo.insert! %Business{name: "Company 2", description: "Short description ...", tag: "Marketing", year: 2000 } +Repo.insert! %Business{name: "Company 3", description: "Short description ...", tag: "Accounting", year: 2000 } + +alias BusiApi.Directory.Colaborator +Repo.insert! %Colaborator{name: "Jhon", lastname: "Doe", email: "some@gmail.com", business_id: 1 } +Repo.insert! %Colaborator{name: "Jane", lastname: "Dow", email: "some@gmail.com", business_id: 2 } +Repo.insert! %Colaborator{name: "Some", lastname: "Other", email: "some@gmail.com", business_id: 3 }