Skip to content

multi transfers #460

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 8, 2019
Merged

multi transfers #460

merged 2 commits into from
May 8, 2019

Conversation

Morantron
Copy link
Collaborator

@Morantron Morantron commented Feb 14, 2019

Closes #469

multi

Wat

Multi transfers feature according to:

https://community.coopdevs.org/t/transferencias-de-horas-a-multiples-usuarios/807/2

The implementation consists of two main pieces:

  • An old-school server-side rendered form, in a multi-step wizard fashion.
  • A set of services objects that manages the creation of the actual transfers in DB.

The form

The form backend

A form divided in multiple steps. All steps are rendered, but only the current one is displayed through CSS.

The wizard starts in this URL

We use GET here so we can link to the initial step with an ordinary link

GET /multi/step/1

The action of the <form /> element points to the next step, and steps are propagated through form data using POST method/

We use POST here to propagate params

POST /multi/step/2
POST /multi/step/3

etc...

The form detects if it's in the last step, to point to the controller action that actually creates the transfers.

The form frontend

I had to add some JS ( SORRY ENRICO ).

I'm reusing jQuery select2 plugin, to mimic pre-existing behaviour when selecting the source/target of transfers. I had to address some jQuery weirdness ( old school TM ), isolated and documented into a separate file multi_select2.js.

Operation services

There are three type of operations ( although only 2 are used ).

  • OneToOne
  • ManyToOne
  • OneToMany

All these are implemented by subclassing Operations::Transfers::Base. The only differing behaviour is where/from the transfers must happen ( check base class for moar docs ). Base class contains common behavior of creating the Transfer objects within a transaction.

There is also a factory function, which receives an array of ids called from, to. Based on the length of the arrays it's able to determine what type of operation it should instantiate.

@Morantron Morantron added the wip label Feb 14, 2019
@Morantron Morantron force-pushed the feature/multi-transfers branch from c4ed91a to 8c1de77 Compare February 14, 2019 18:20
@sseerrggii
Copy link
Contributor

#469

@Morantron Morantron force-pushed the feature/multi-transfers branch from cf753e8 to f058e34 Compare March 21, 2019 16:52
@Morantron Morantron force-pushed the feature/multi-transfers branch 2 times, most recently from b91341b to 394add4 Compare April 16, 2019 15:49
@Morantron Morantron force-pushed the feature/multi-transfers branch 2 times, most recently from 6e50b35 to 125380d Compare April 16, 2019 16:33
@Morantron Morantron requested review from markets, enricostano and sauloperez and removed request for markets and enricostano April 16, 2019 16:34
Copy link
Collaborator

@markets markets left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Morantron looks really nice in general 👍, to be honest, I don't know well this part (transfers), so I just added some "high level" comments (most important is the one related to front-end validations ✂️).

Also, I want to add a couple of comments:

  • Travis is failing 🔴
  • "There are three type of operations ( although only 2 are used )." => can we just implement (and maintain) the 2 that are really used? It will also reduce the diff.

if amount > 0
form.submit()
else
$(form).find('.form-actions .error').removeClass('invisible').show()
Copy link
Collaborator

@markets markets Apr 16, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Morantron why this check + front-end validations were removed? We introduced it recently, in #421

Copy link
Collaborator

@markets markets Apr 23, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Morantron @sseerrggii I think we should leave this front-end validation working for both scenatios: regular transfer and multi-transfers. We have back-end and DB constraints, but I'd like to keep this friendly i18n front-end validation 👌

<label class="error invisible"><%= t ".error_amount" %></label>

If you try a multi-transfer with amount 0, probably you will see some ROLLBACK ⚠️ in the log.

Regular transfer example 👇
Captura de pantalla 2019-04-23 a las 20 20 34

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've rearranged the code to preserve this behavior. I only need the bits that fill the hidden input with the total amount of seconds ( hours + minutes ). Validation logic breaks the multi transfer wizard, since we always render the field but it might not be filled yet.

Copy link
Collaborator

@markets markets Apr 29, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Morantron I think it's important to keep this front-end validation, I just tried locally this branch and I get the following weird behavior:

  1. I fill with amount 0 (0 hours, 0 mins)
  2. Transfers created successfully as a flash message
  3. I see a db ROLLBACK in the log and the transfer isn't created at all 😲

That's really confusing, IMHO we should improve it before shipping it :)

Maybe we can try something like: perform js validation only in specific step.

@Morantron Morantron force-pushed the feature/multi-transfers branch from a424409 to fff1148 Compare April 17, 2019 12:53
@sseerrggii sseerrggii requested a review from markets April 23, 2019 07:48
@Morantron Morantron requested a review from markets April 29, 2019 14:31
@Morantron
Copy link
Collaborator Author

I'll add some controller/feature tests, and everything will be verdura/green 🙌

Copy link
Collaborator

@markets markets left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Morantron only a couple of items from my side 🙏 😄

  • Amount validation (discussion here 👉 #460 (comment))
  • I think we should add more validations to these multi steps form. Example: now I can leave from or to empty via the UI, and at the end of the process I get 500 error:
NoMethodError - undefined method `length' for nil:NilClass:
  app/services/operations/transfers.rb:14:in `transfer_klass'
  app/services/operations/transfers.rb:6:in `create'
  app/controllers/multi_transfers_controller.rb:19:in `create'

@Morantron
Copy link
Collaborator Author

@markets true dat, I think I've fixed the validation issues, try again plz 🙏

@markets
Copy link
Collaborator

markets commented Apr 30, 2019

@Morantron just 1 missing weird behavior (and crash 💥) now:

  • select "Many to one" type
  • from: select only 1
  • to: select 1

It crashes with:

ArgumentError - Unknown type of transfer:
  app/services/operations/transfers.rb:19:in `transfer_klass'
  app/services/operations/transfers.rb:6:in `create'
  app/controllers/multi_transfers_controller.rb:19:in `create'

@Morantron Morantron force-pushed the feature/multi-transfers branch 2 times, most recently from 2366207 to 9e151eb Compare May 3, 2019 13:58
@Morantron
Copy link
Collaborator Author

Fixed the broken case, which is covered by the OneToOne transfer operation ( i brought it back ).

It's all green now

image

@markets
Copy link
Collaborator

markets commented May 3, 2019

Cool @Morantron 👌 ✅

2.4% extra coverage 🔝 😸

Copy link
Contributor

@enricostano enricostano left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👏

@enricostano
Copy link
Contributor

@sseerrggii we're ready to give it a final manual test. Please deploy it to staging and test it whenever you can. Also take in account Marc's latest comments like #460 (comment)

@sseerrggii
Copy link
Contributor

Testing I noticed that as no-admin user I can access through URL https://staging.timeoverflow.org/multi/step/1 and create transfers 😱

Can we ensure on backend that normal users only can pay from their accounts? 🙏

Also can we use key title something like multi_transfers? because we will have some languages pending to translate and english is better than nothing

FireShot Capture 214 - Banc del Temps de Gràcia - staging timeoverflow org

everything else seems to work perfectly 💪

@Morantron Morantron force-pushed the feature/multi-transfers branch from 9e151eb to 2108e6c Compare May 7, 2019 08:00
@Morantron
Copy link
Collaborator Author

added multi transfer policy to prevent regular users from accessing the controller and changed that copy 💃

@sseerrggii
Copy link
Contributor

sseerrggii commented May 7, 2019

@Morantron you forget to change <h1> title in view 89efb95

@sseerrggii
Copy link
Contributor

sseerrggii commented May 7, 2019

Now everything is ok 🎉

giphy (7)

@enricostano
Copy link
Contributor

@sseerrggii @Morantron can we remove the needs testing tag? Are we ready to merge?

ARE YOU SURE?

@sseerrggii
Copy link
Contributor

Yes @enricostano ! Tested ✔️

@enricostano enricostano merged commit 8de9ca4 into develop May 8, 2019
@enricostano enricostano deleted the feature/multi-transfers branch May 8, 2019 12:26
@sseerrggii sseerrggii mentioned this pull request May 16, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Multi transfers
4 participants