Giter VIP home page Giter VIP logo

avia's People

Contributors

anantanant2015 avatar arjun289 avatar ashish173 avatar evgk avatar gabrielgrover avatar gopalshimpi avatar jaypal412 avatar jeshan7 avatar jyotigautam avatar kanishkablack avatar oyeb avatar pkrawat1 avatar ramansah avatar sagarkarwande avatar sakinaboriwala avatar suhasdombale123 avatar taimoorrana avatar vikramjadon921995 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

avia's Issues

Set up configuration system

Use cases

  1. Configure the payment_method seed data, the :codes are currently hardcoded and it will become much simpler to maintain changes to them if they are defined in a single place. comment

Format

  1. YAML
  2. JSON
  3. INI

Handling email delivery using Bamboo Mailer in the background.

To deliver emails in the background Bamboo offers deliver_later on our Mailers so that it won't block our requests.
By default delivering later uses Bamboo.TaskSupervisorStrategy. This strategy sends the email right away, but does so in the background without linking to the calling process, so errors in the mailer won't bring down your app.
To create a custom strategy we can implement Bamboo.DeliverLaterStrategy. For example, strategies for adding emails to a background processing queue such as exq or toniq.

mix task for seeding data

Create a mix task to seed data for the core app.
The applicaitons needed to seed data should be loaded only during the seed operation.

Add Constants File in the system for all the hardcoded strings in the App

Current Situation:
Currently we are directly using the hardcoded strings wherever in need.
like for payment types chk and ccd is hardcoded wherever needed.
Also for usual messages and error messages we are hardcoding the lines.

Intended situation:
In future if we want to make any change we will have to change the every occurrence of hardcoded string in the app.
There should be a single point of truth/source where once a change is made, will reflect in the entire system.

Proposed Fix
Create a Constant File, where will be can use maps for different types of strings.
E.g: PAYMENT_TYPES = %{chk: 'chk', ccd: 'ccd'}
Enums can also be used.

Any other suggestions are welcomed πŸ˜„

Improve `User`, add Model and tests

Schema.User

  • Refactor the changeset functions to match those in Schema.LineItem Schema.Order (add the action argument)
  • Change @required_fields, @password_fields to @create_fields and @update_fields
  • Might need migrations:
    • :password_hash should never be null.
    • Change naive_datetime to utc_datetime.
    • Add relation to Address (see spree's user schema here). Don't forget to set the :on_delete action. Moved to #38.
    • Remove the ? from boolean fields (:is_admin?).

Model.User

  • This module should have CRUD API, make use of Snitch.Tools.QueryHelper

Tests

  • Schema tests should not use the factory to build/insert User. Write assertions on the changeset itself. Cover all error cases.
  • Model tests. No need to test get and get_all.

Doctests

  • We could add doctests in Schema or Model to show how the password_hash gets computed.

Excellent documentation on how to write doctests. See an example in Model.LineItem and Model.LineItemTest

Factory

  • Improve user_with_address in test/support/factory.ex

Fix docs, variable naming and refactor the changes in #161

PR 161 introduced many breaking changes as all entities that were associated with variants will now be associated with products. Tests that failed due to these changes were fixed, but the docs, variable and method naming need to be fixed. Refer the PR 161 diff to refactor the changes

[Admin] Taxonomy UI fixes

Following things need to be fixed on Taxonomy edit page

  • Taxon edit without image does not work
  • Handle all the API errors on display them on UI.
  • Refactor the API form generation for create and edit.
  • Test if it is possible to send array values in form for variation theme. This will reduce conversion logic in taxon schema.
    • When phoenix form gets submitted the values for themes is like ["1", "2"], but now with API call the themes ids are sent like this "1,2,3".

No unique indexes on countries and states

Though the changeset handles unique_constraint errors, none have been specified in the migrations. This leads to duplication when core.seed is run more than once.

UI for promotions feature

Create promotions creation UI in admin interface.

First Task

List of tasks for create flow:-

  • Create form for promotion create fields.
  • Create sub-section for promotion rules case.
  • Create sub-section for promotion actions case.

Second Task

List of tasks for READ, UPDATE, DELETE flow:-

  • List all promotions.
  • Edit a promotion.
  • Delete and deactivate a promotion.

Promotion create screen.

screen shot 2018-10-25 at 6 43 11 pm

Promotion rules and Promotion actions.

screen shot 2018-10-25 at 6 44 26 pm

Set up Card schema and model

Tracker Story

Schema Card

  • changeset functions must be like the ones in Schema.Payment, with an action argument. This will make it easy to write the Model.
  • Associate Card with CardPayments. Is the Card created along with the parent CardPayment or separately? If created with the parent, use cast_assoc in CardPayment's changeset.

Model

  • This module should have CRUD API, make use of Snitch.Tools.QueryHelper

Tests

  • Schema tests should not use the factory to build/insert Card. Write assertions on the changeset itself. Cover all error cases.
  • Model tests. No need to test get and get_all.

Doctests (optional)

Excellent documentation on how to write doctests. See an example in Model.LineItem and Model.LineItemTest

small refactoring

I just for fun refactored a couple of functions in avia/apps/admin_app/lib/admin_app/order/order.ex.
The get_rummage function contains a risky String.to_atom call (see https://hexdocs.pm/elixir/String.html#to_atom/1). I removed it. The rest of the changes could speak for itself (feel free to ask if you have questions). There is one order_list function now. I have no elixir editor from where I work, so maybe there are errors in the code.

  def order_list(order_state, sort_order) do
    orders =
      get_rummage(sort_order)
      |> query_orders(order_state)
      |> load_orders()
	  
    case order_state do
      "complete" ->  orders 
      _          ->  orders |> Enum.filter(fn order -> filter_order?(order.packages, order_state) end)
    end  
  end
  
  defp filter_order?(packages, "pending"), do: 
    Enum.member?(packages, "processing")
 
  defp filter_order?(packages, "unshipped"), do: 
    Enum.member?(packages, "ready")
	
  defp filter_order?(packages, "shipped"), do: 
    Enum.any?(packages, fn package ->
      package.state == "shipped" || package.state == "delivered"
    end)
  
  defp get_rummage(sort_order) do
    case sort_order do
      nil ->
        %{}

      "asc" ->
        %{
          sort: %{field: :inserted_at, order: :asc}
        }
      "desc" ->
        %{
          sort: %{field: :inserted_at, order: :desc}
        }		
    end
  end  
  
  defp query_orders(rummage, order_state) do
    {queryable, _rummage} = Order.rummage(rummage)

    case order_state do
      complete" -> from(p in queryable, where: p.state == "complete")
      _         -> from(p in queryable, where: p.state == "confirmed") 
    end
  end  

Stock Transfer CRUD with test

Pivotal #155950953

Schema

reference: keyword
source_location_id: source stock location (optional)
destination_location_id: destination stock location (required)
number: unique identifier to be used in UI

Model

Exposes only Create, Get, Get all functions. Just like stock movement. This should not be deleted/updated. Instead will be offset using new record.

Edit product fixes

The scenario needs to be handled where the selected variation-theme has empty option types on editing a product and creating variants for it.
Steps to reproduce the error:

  1. Try to create a variation theme with empty/invalid option type.
  2. Add a taxon in a taxonomy with the variation theme created above.
  3. Create a product under the above taxon and try to add variants with the variation theme created in step1(one with invalid option type) and you'll get the following error:
    ** (BadMapError) expected a map, got: nil

Can't "use" snitch

How is Snitch going to be used (or customized)?

Snitch is not a library, it's an app. So our users won't be adding {:snitch, "> 0.1"} to their deps. They'll have to clone it and actually edit Snitch itself.

Why is this important?

  • snitch_core comes with its own Repo. ❌
    • Our user must supply his repo to Snitch.
  • Snitch must read from config which payment gateway should be used. This configuration cannot lie under :snitch_core OTP app.
  • This is slightly related to #10, see this comment

Perhaps...

Snitch is like a demo app that uses the snitch_core library. In that case,

  • snitch_core should be added as a dependency.
  • snitch_core must fetch stuff like Repo config, Gateway config from outside the lib.
  • snitch_core provides some mix tasks to seed the user's Repo.
  • how should we test snitch_core if we do the above?

Generic type 'NguCarousel<T>' requires 1 type argument(s)

Hi I am trying to run the application but getting the following error:

ERROR in src/app/landing/components/lp-banner/lp-banner.component.ts(14,26): error TS2314: Generic type 'NguCarousel<T>' requires 1 type argument(s).
src/app/product/components/product-detail-page/product-images/product-images.component.ts(55,7): error TS2322: Type 'number' is not assignable to type 'CarouselInterval'.
src/app/product/components/product-detail-page/product-images/product-images.component.ts(56,7): error TS2322: Type '{ visible: boolean; pointStyles:
string; }' is not assignable to type 'boolean'.
src/app/product/components/product-detail-page/product-images/product-images.component.ts(90,7): error TS2322: Type 'true' is not assignable to type 'Touch'.

I think it is asking to provide a type to generic, but even if I do so it still throws an error.
I already saw a similar issue here, but no solution provided. uiuniversal/ngu-carousel#106
Can anyone please help I am stuck. Apologies if I missed anything, Please let me know if you need any extra information. Thanks.

Making domain as boundary to access snitch_core functionality.

Context

At present we don't have any rule for limiting the access of domain, model and schema functions outside snitch_core.

The possible scenarios are

  1. Allowing model functions to be used outside snitch_core.

    • pros

      1. CRUD functions for a model don't need to be re-written in the domain module for accessing in another application so no code repetition.
    • cons

      1. For large projects IMO and as per the project I have experience with it's always better to have a single point of access to another application.
  2. Allowing all the access to snitch_core through domain modules.

    • pros
      1. Single point of accessibility so there is always a consistency maintained.
    • cons
      1. Code repetition in case of CRUD functions which are already there.

These are my views, I would like other people to put in their inputs and we can create some conventions and rules around that to be followed in snitch.

[Core] On product delete remove it from wishlist

We need to come up with an approach to handle product deletions.

Usually, products are present in many users carts. Either this should not be allowed or we should just deactivate(soft delete) the product and show to the user in the wish list that the product has been deactivated or something.

[Admin] Product state cannot be changed

Admin can only activate product to active once, next time it won't work.
Step to reproduce:

  • Navigate to product listing
  • Change state of any product in draft section to active (It will change the state)
  • Now try again to change the state for any product to active. (It wont allow to change the state until we visit to product page without any filters)

Listing does not get active if product with no variants

If a listing is in in-active state and there are no variants for it then trying to change the state to active does not do anything. No errors are shown and the status also does not change.

However, if variants are created for the product then in that case the status can be changed from in-active to active.

Transition from cart to address is wrong

According to definitions of the state machine, an order in cart state has no address.
But, the DefaultMachine.add_addresses can associate an address, then fail if shipment computation fails -- without rolling back the address. πŸ˜–
This will keep the order in cart state, with an address.
That's not what we want:

  1. fail if the address association fails.
  2. succeed even if shipment computation fails.

Forget password feature bugs

Bug

  • when user enters email for resetting password it throws internal server error. So currently user is not able to reset password.

Misplaced UI

UI for forget password page is misplaced.

Sub optimal splitting by weight splitter

Scenario

When splitting an "individual" item that is ordered in a large quantity, the split does not consider previously prepared packages that still have some space in them.

  1. Threshold: 150 g
  2. Weights of bins prepared till now = [120 g, 110 g]
  3. Weight and quantity of item under consideration: 20 g x 15

Current output

List of bins/packages after processing this item:
[120, 110, 140, 140, 20]

Expected output

List of bins/packages after processing this item:
[140, 150, 140, 100]

Modify the dir structure of the snitch project

Current naming and dir structure

|-- apps
    |-- core
         |-- config 
         |-- lib
             |-- core
                 |-- snitch
                     |-- data
                         |-- schema
                         |-- model
                 |-- tools
                 |-- seed

Suggested naming and dir structure

|-- apps
    |-- snitch
         |-- config 
         |-- lib
             |-- snitch
                 |-- data
                     |-- schema
                     |-- model
                 |-- tools
             |-- seed
  • The suggested structure will change the name of the application itself.
  • Confirmation needed.

Restructure 2.0

Approved tasks

We missed a few details in #18 😒

  1. According to the final dir structure, there should be no "core/" in lib/.
  2. query_helper.ex is inside query_helper/. Let's move it out up.
  3. Do we really need the Data namespace? We can keep the folder perhaps.
  4. Our changeset functions have an action argument. It should be the first argument, not the last. The last an be made a keyword if need be.
  5. Remove seed/ from lib and place them in priv/repo/

Rejected tasks

  1. __using__ macro in schema.ex, model.ex, domain.ex must self-alias, so that when we do use Snitch.Data.Schema, we don't have to also do alias Snitch.Data.Schema.
    • No longer relevant.

  2. use Snitch.Data.Schema is allowed only in lib/data/schema/*.ex, and likewise for Model and Domain. Everywhere else, they should be aliased.
    • Rationale: We use a module to become like it. For example, all schemas "use" Ecto.Schema, because they are schemas.
    • Culprit: factory.ex
    • No longer relevant

Tasks that moved elsewhere

  1. QueryHelper.update args should be swapped, struct first and then params.
  2. Many Model functions have this argument: id_or_instance.
    a. Let's rename it to id_or_struct (because there's no concept of "instance" in Elixir).
    b. Or consistently accept only ids if the function does not load the record from DB, and <struct_name> if the function actually operates on the struct.

Dir structure when issue was opened

$ tree lib
lib
β”œβ”€β”€ core
β”‚Β Β  β”œβ”€β”€ application.ex
β”‚Β Β  β”œβ”€β”€ data
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ model
β”‚Β Β  β”‚Β Β  β”‚Β Β  β”œβ”€β”€ line_item.ex
β”‚Β Β  β”‚Β Β  β”‚Β Β  β”œβ”€β”€ model.ex
β”‚Β Β  β”‚Β Β  β”‚Β Β  β”œβ”€β”€ order.ex
β”‚Β Β  β”‚Β Β  β”‚Β Β  └── stock
β”‚Β Β  β”‚Β Β  β”‚Β Β      β”œβ”€β”€ stock.ex
β”‚Β Β  β”‚Β Β  β”‚Β Β      β”œβ”€β”€ stock_item.ex
β”‚Β Β  β”‚Β Β  β”‚Β Β      └── stock_location.ex
β”‚Β Β  β”‚Β Β  └── schema
β”‚Β Β  β”‚Β Β      β”œβ”€β”€ address.ex
β”‚Β Β  β”‚Β Β      β”œβ”€β”€ country.ex
β”‚Β Β  β”‚Β Β      β”œβ”€β”€ line_item.ex
β”‚Β Β  β”‚Β Β      β”œβ”€β”€ order.ex
β”‚Β Β  β”‚Β Β      β”œβ”€β”€ schema.ex
β”‚Β Β  β”‚Β Β      β”œβ”€β”€ state.ex
β”‚Β Β  β”‚Β Β      β”œβ”€β”€ stock
β”‚Β Β  β”‚Β Β      β”‚Β Β  β”œβ”€β”€ stock.ex
β”‚Β Β  β”‚Β Β      β”‚Β Β  β”œβ”€β”€ stock_item.ex
β”‚Β Β  β”‚Β Β      β”‚Β Β  └── stock_location.ex
β”‚Β Β  β”‚Β Β      β”œβ”€β”€ user.ex
β”‚Β Β  β”‚Β Β      └── variant.ex
β”‚Β Β  β”œβ”€β”€ domain
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ domain.ex
β”‚Β Β  β”‚Β Β  └── stock
β”‚Β Β  β”‚Β Β      └── inventory.ex
β”‚Β Β  β”œβ”€β”€ repo.ex
β”‚Β Β  β”œβ”€β”€ seed
β”‚Β Β  β”‚Β Β  └── country_state_seed.ex
β”‚Β Β  └── tools
β”‚Β Β      └── helpers
β”‚Β Β          └── query_helper
β”‚Β Β              └── query_helper.ex
└── snitch.ex

Associate products with properties

As of now both the schemas exist but the functionality for their relationship is not present.

Associate product schema with property schema such that products can be associated properties.

Create a Setup Doc

Currently there is not setup doc for this app, create one.
Things in setup doc:

  1. Installation of elixir
  2. How to install deps
  3. Extra libraries needed to be installed like postgres
  4. How to configure the app. e.g for database config for different system
  5. How to start the app
  6. How to run tests
  7. How to see the coverage

Please feel free to add what extra will be needed πŸ˜„

Refactor QueryHelper and Models

The QueryHelper brings convenience at a cost. It has polymorphic clauses for update, delete, get which accept integers/nil in addition to struct.

  • This makes it hard to document and improve.
  • We can reduce arity of most calls to QH if we only accept Ecto.Schema structs, because these struct have a lot of metadata.
  • These methods that work with integer IDs have not been of much use, and I don't think they will ever be.

Tasks

  • Make sure the last arg of all calls is a keyword list of options. This is important because all Ecto.Repo functions accept a keyword list of DB options.
  • Reduce arity of all calls by
    • finding the Ecto.Repo at compile time (or fetch it from the keyword list)
    • finding the schema of struct from the metadata
  • Remove commit_if_valid/2 because it serves no purpose.
  • Update all Models to reflect changes made in QueryHelper.
  • Add method call for soft delete.

`QueryHelper.delete` always returns `{:error, :not_found}`

def delete(schema, id, repo) when is_integer(id) do
  with {:ok, instance} <- repo.get(schema, id) do
    delete(schema, instance, repo)
  else
    {:error, :not_found}
  end
end

The with clause always fails because Ecto.Repo.get/2) always returns Ecto.Schema.t or nil and never a tuple.

Order should allow zero LineItems?

Creating Updating an order without by removing its LineItems fails because of the way we compute order.total:

** (Enum.EmptyError) empty error
    (elixir) lib/enum.ex:1855: Enum.reduce/2
    (snitch_core) lib/core/data/schema/order.ex:92: Snitch.Data.Schema.Order.compute_totals/1
    (snitch_core) lib/core/tools/helpers/query_helper/query_helper.ex:37: Snitch.Tools.QueryHelper.update/4

This is also related to the way we handle money.

  1. The order total is the sum of line_item.total (if they are all in the same currency, the other case is not handled).
  2. Order schema sets the default price to #Money<0, :USD>, but why USD?
    a. We should probably pick the "default" curreny from application config.
    b. Does it matter which currency it is? Zero in all currencies is the same πŸ˜„
  3. When we have no line_items, The order.total must be set to zero... but in which currency?

There are 2 issues here:

  1. Should we allow setting an Order's line_items to []?
  2. Decide what to do about the default currency.

Add Stock Movement for stocks

  • Adds schema, model and test cases for stock movements.
  • Stock movement is never updated or deleted. So I have not added update/delete methods model.

Plugins architecture proposal

With the basic e-commerce platform released we are set to start working on supporting plugins for aviacommerce.

Plugins for aviacommerce would work similar to how magento and shopify plugins work. A seller can install these apps in their online store and would be able to use the features of this plugin. For eg. If a seller installs MailChimp plugin/application then they would get following functionalities with it broadly categorised in 2 categoreis:-

  1. A new tab/view in the admin dashboard with a custom option for MailChimp like a list of all abandoned carts by customers.
  2. Ability to push data to the MailChimp servers for eg. when a new user signs up for registering the user at mailchimp's end.

The platform would be powered by at least 200 to 300 plugins. Every seller will integrate an almost unique combination of plugins. From this we can infer a few things about the behaviour of plugins:-

  1. We can't have all the plugins already installed the application and activate them based on the sellers choice by including the package name in mix.exs file.
  2. Even if we inject code using the approach mentioned here we still have to include the plugin name in the project.

So, the need is to have the plugins(and their associated code) included individually for each seller. Aviacommerce is a platform supporting multi-tenancy.

The problem ahead of us is to come up with an approach to achieve this dynamic nature of code injection for each individual seller using the plugins(service specific).

Approach 1

One of the approach we discussed initially was a way to highjack the control flow. For the sake of discussing this approach lets take a basic requirement of sending an event trigger for product view to a marketing service. A naive implementation would be triggering an async job/worker to send the event. Code for this would go in the products controller show method if we don’t have support for plugins in place. However, If we have plugins support then we’d have a plugin with code(service specific). On activation this plugin code would highjack the product controller show method , trigger the async code and return control to the platform products controller show method.

This is a very basic use case and does not provide solution for exposing views from the plugins.

Approach 2

...

Plugins usage

Sellers should be able to use the user interface to activate plugins to integrate third party services. These activations happen in realtime.

For the sake of POC we can just implement the plugins for services which just send a trigger to a third party service. For eg. sending orders list to sendgrid, sending events to segment.com and similar user cases.

Ejabbered(Erlang project) has implemented a plugin approach similar to what we want in the system.

Question about product schema

This isn't really an issue, but more of a question:

Why did you choose to model Products and Product Variants in a single table? Are there any concerns with challenges of having to manage name/description/meta-description/etc of many product variants at once?

Why not a "Products" table that contains common fields and a "Variants" table that contains variant-specific attributes like prices, options, etc?

User has no addresses

Requirement

  • Addresses that are "saved" by the user are associated with her. These saved addresses can be used during checkout as billing and/or shipping address.
  • A new Address record is created if the user does not use a saved address as billing/shipping address during checkout.
  • User can edit (or update) saved addresses.
    • What if this address was used in some previous order?

      Add a new Address record. From the old record remove the association with the user. All orders using the old address will thus remain intact.

Discussion

  1. A foreign_key in Address referencing User that can be null should suffice. Or we could make a join table (that would be overkill as User:Address::1:n, and not m:n).

Missing an open source license

This looks like a neat project! Although, I have a question. The website proclaims that this is an "Open Source E-Commerce framework", but I cannot find an open source license anywhere in the code. Do you have one in mind?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.