commit 25b3dc3063930af2a2fdbc1d94292d0b8929964c Author: Zach Daniel Date: Fri Jul 21 20:27:52 2023 -0400 init diff --git a/.formatter.exs b/.formatter.exs new file mode 100644 index 0000000..3392b8e --- /dev/null +++ b/.formatter.exs @@ -0,0 +1,5 @@ +# Used by "mix format" +[ + import_deps: [:ash], + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] +] diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a2a9d24 --- /dev/null +++ b/.gitignore @@ -0,0 +1,26 @@ +# The directory Mix will write compiled artifacts to. +/_build/ + +# If you run "mix test --cover", coverage assets end up here. +/cover/ + +# The directory Mix downloads your dependencies sources to. +/deps/ + +# Where third-party dependencies like ExDoc output generated docs. +/doc/ + +# Ignore .fetch files in case you like to edit your project deps locally. +/.fetch + +# If the VM crashes, it generates a dump, let's ignore it too. +erl_crash.dump + +# Also ignore archive artifacts (built via "mix archive.build"). +*.ez + +# Ignore package tarball (built via "mix hex.build"). +ash_double_entry-*.tar + +# Temporary files, for example, from tests. +/tmp/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..29ee2e2 --- /dev/null +++ b/README.md @@ -0,0 +1,21 @@ +# AshDoubleEntry + +**TODO: Add description** + +## Installation + +If [available in Hex](https://hex.pm/docs/publish), the package can be installed +by adding `ash_double_entry` to your list of dependencies in `mix.exs`: + +```elixir +def deps do + [ + {:ash_double_entry, "~> 0.1.0"} + ] +end +``` + +Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc) +and published on [HexDocs](https://hexdocs.pm). Once published, the docs can +be found at . + diff --git a/lib/account/account.ex b/lib/account/account.ex new file mode 100644 index 0000000..952e6cc --- /dev/null +++ b/lib/account/account.ex @@ -0,0 +1,15 @@ +defmodule AshDoubleEntry.Account do + @account %Spark.Dsl.Section{ + name: :account + } + + @sections [@account] + + @transformers [ + AshDoubleEntry.Account.Transformers.AddStructure + ] + + use Spark.Dsl.Extension, + sections: @sections, + transformers: @transformers +end diff --git a/lib/account/transformers/add_structure.ex b/lib/account/transformers/add_structure.ex new file mode 100644 index 0000000..9d85822 --- /dev/null +++ b/lib/account/transformers/add_structure.ex @@ -0,0 +1,17 @@ +defmodule AshDoubleEntry.Account.Transformers.AddStructure do + use Spark.Dsl.Transformer + + def transform(dsl) do + dsl + |> Ash.Resource.Builder.add_attribute(:balance, :decimal, + allow_nil?: false, + default: Decimal.new(0), + writable?: false + ) + |> Ash.Resource.Builder.add_attribute( + :currency, + :string, + allow_nil?: false + ) + end +end diff --git a/lib/ash_double_entry.ex b/lib/ash_double_entry.ex new file mode 100644 index 0000000..29380b8 --- /dev/null +++ b/lib/ash_double_entry.ex @@ -0,0 +1,2 @@ +defmodule AshDoubleEntry do +end diff --git a/lib/transfer/info.ex b/lib/transfer/info.ex new file mode 100644 index 0000000..12eb911 --- /dev/null +++ b/lib/transfer/info.ex @@ -0,0 +1,3 @@ +defmodule AshDoubleEntry.Transfer.Info do + use Spark.InfoGenerator, extension: AshDoubleEntry.Transfer, sections: [:transfer] +end diff --git a/lib/transfer/transfer.ex b/lib/transfer/transfer.ex new file mode 100644 index 0000000..8f90625 --- /dev/null +++ b/lib/transfer/transfer.ex @@ -0,0 +1,22 @@ +defmodule AshDoubleEntry.Transfer do + @account %Spark.Dsl.Section{ + name: :transfer, + schema: [ + account_resource: [ + type: Ash.OptionsHelpers.ash_resource(), + doc: "The resource to use for account balances", + required: true + ] + ] + } + + @sections [@account] + + @transformers [ + AshDoubleEntry.Transfer.Transformers.AddStructure + ] + + use Spark.Dsl.Extension, + sections: @sections, + transformers: @transformers +end diff --git a/lib/transfer/transformers/add_structure.ex b/lib/transfer/transformers/add_structure.ex new file mode 100644 index 0000000..e363b31 --- /dev/null +++ b/lib/transfer/transformers/add_structure.ex @@ -0,0 +1,18 @@ +defmodule AshDoubleEntry.Transfer.Transformers.AddStructure do + use Spark.Dsl.Transformer + + def transform(dsl) do + dsl + |> Ash.Resource.Builder.add_attribute(:amount, :decimal, + allow_nil?: false, + default: Decimal.new(0), + writable?: false + ) + |> Ash.Resource.Builder.add_attribute(:converted_amount, :decimal, writable?: true) + |> Ash.Resource.Builder.add_relationship( + :belongs_to, + :account, + AshDoubleEntry.Transfer.Info.transfer_account_resource(dsl) + ) + end +end diff --git a/mix.exs b/mix.exs new file mode 100644 index 0000000..eae42e2 --- /dev/null +++ b/mix.exs @@ -0,0 +1,29 @@ +defmodule AshDoubleEntry.MixProject do + use Mix.Project + + def project do + [ + app: :ash_double_entry, + version: "0.1.0", + elixir: "~> 1.15", + start_permanent: Mix.env() == :prod, + deps: deps() + ] + end + + # Run "mix help compile.app" to learn about applications. + def application do + [ + extra_applications: [:logger] + ] + end + + # Run "mix help deps" to learn about dependencies. + defp deps do + [ + {:ash, "~> 2.13"} + # {:dep_from_hexpm, "~> 0.3.0"}, + # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"} + ] + end +end diff --git a/mix.lock b/mix.lock new file mode 100644 index 0000000..359fab3 --- /dev/null +++ b/mix.lock @@ -0,0 +1,16 @@ +%{ + "ash": {:hex, :ash, "2.13.0", "b4c36748414b64912a77c195e9350dc546fe2461b246b61a272a2d6e9f2d0e14", [:mix], [{:comparable, "~> 1.0", [hex: :comparable, repo: "hexpm", optional: false]}, {:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:earmark, "~> 1.4", [hex: :earmark, repo: "hexpm", optional: true]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8.0", [hex: :ets, repo: "hexpm", optional: false]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: false]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:spark, ">= 1.1.20 and < 2.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:stream_data, "~> 0.5.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c9211a07154fa477f7696bd70ad66e78fac7a0e80652e62d93eef9821af6dfaf"}, + "comparable": {:hex, :comparable, "1.0.0", "bb669e91cedd14ae9937053e5bcbc3c52bb2f22422611f43b6e38367d94a495f", [:mix], [{:typable, "~> 0.1", [hex: :typable, repo: "hexpm", optional: false]}], "hexpm", "277c11eeb1cd726e7cd41c6c199e7e52fa16ee6830b45ad4cdc62e51f62eb60c"}, + "decimal": {:hex, :decimal, "2.1.1", "5611dca5d4b2c3dd497dec8f68751f1f1a54755e8ed2a966c2633cf885973ad6", [:mix], [], "hexpm", "53cfe5f497ed0e7771ae1a475575603d77425099ba5faef9394932b35020ffcc"}, + "ecto": {:hex, :ecto, "3.10.3", "eb2ae2eecd210b4eb8bece1217b297ad4ff824b4384c0e3fdd28aaf96edd6135", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "44bec74e2364d491d70f7e42cd0d690922659d329f6465e89feb8a34e8cd3433"}, + "elixir_make": {:hex, :elixir_make, "0.7.7", "7128c60c2476019ed978210c245badf08b03dbec4f24d05790ef791da11aa17c", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}], "hexpm", "5bc19fff950fad52bbe5f211b12db9ec82c6b34a9647da0c2224b8b8464c7e6c"}, + "ets": {:hex, :ets, "0.8.1", "8ff9bcda5682b98493f8878fc9dbd990e48d566cba8cce59f7c2a78130da29ea", [:mix], [], "hexpm", "6be41b50adb5bc5c43626f25ea2d0af1f4a242fb3fad8d53f0c67c20b78915cc"}, + "jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"}, + "nimble_options": {:hex, :nimble_options, "1.0.2", "92098a74df0072ff37d0c12ace58574d26880e522c22801437151a159392270e", [:mix], [], "hexpm", "fd12a8db2021036ce12a309f26f564ec367373265b53e25403f0ee697380f1b8"}, + "picosat_elixir": {:hex, :picosat_elixir, "0.2.3", "bf326d0f179fbb3b706bb2c15fbc367dacfa2517157d090fdfc32edae004c597", [:make, :mix], [{:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "f76c9db2dec9d2561ffaa9be35f65403d53e984e8cd99c832383b7ab78c16c66"}, + "sourceror": {:hex, :sourceror, "0.12.3", "a2ad3a1a4554b486d8a113ae7adad5646f938cad99bf8bfcef26dc0c88e8fade", [:mix], [], "hexpm", "4d4e78010ca046524e8194ffc4683422f34a96f6b82901abbb45acc79ace0316"}, + "spark": {:hex, :spark, "1.1.20", "48f4dd3bed1e16d43a5084a0277f2d8c3adac9bcfa07dfdac9931b025b75480b", [:mix], [{:nimble_options, "~> 0.5 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:sourceror, "~> 0.1", [hex: :sourceror, repo: "hexpm", optional: false]}], "hexpm", "b48d77cdcbc3f00a6e67f447d9860c390f790baf4e7d879d7c6bfd37109c4659"}, + "stream_data": {:hex, :stream_data, "0.5.0", "b27641e58941685c75b353577dc602c9d2c12292dd84babf506c2033cd97893e", [:mix], [], "hexpm", "012bd2eec069ada4db3411f9115ccafa38540a3c78c4c0349f151fc761b9e271"}, + "telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"}, + "typable": {:hex, :typable, "0.3.0", "0431e121d124cd26f312123e313d2689b9a5322b15add65d424c07779eaa3ca1", [:mix], [], "hexpm", "880a0797752da1a4c508ac48f94711e04c86156f498065a83d160eef945858f8"}, +} diff --git a/test/ash_double_entry_test.exs b/test/ash_double_entry_test.exs new file mode 100644 index 0000000..5e37909 --- /dev/null +++ b/test/ash_double_entry_test.exs @@ -0,0 +1,8 @@ +defmodule AshDoubleEntryTest do + use ExUnit.Case + doctest AshDoubleEntry + + test "greets the world" do + assert AshDoubleEntry.hello() == :world + end +end diff --git a/test/test_helper.exs b/test/test_helper.exs new file mode 100644 index 0000000..869559e --- /dev/null +++ b/test/test_helper.exs @@ -0,0 +1 @@ +ExUnit.start()