decidim-budgets 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +23 -0
  3. data/Rakefile +2 -0
  4. data/app/assets/config/decidim_budgets_manifest.js +1 -0
  5. data/app/assets/images/decidim/budgets/icon.svg +4 -0
  6. data/app/assets/javascripts/decidim/budgets/projects.js.es6 +28 -0
  7. data/app/assets/stylesheets/decidim/budgets/_budgets.scss +1 -0
  8. data/app/assets/stylesheets/decidim/budgets/budget/_budget-list.scss +32 -0
  9. data/app/assets/stylesheets/decidim/budgets/budget/_budget-meter.scss +78 -0
  10. data/app/assets/stylesheets/decidim/budgets/budget/_progress.scss +17 -0
  11. data/app/commands/decidim/budgets/add_line_item.rb +43 -0
  12. data/app/commands/decidim/budgets/admin/create_project.rb +52 -0
  13. data/app/commands/decidim/budgets/admin/update_project.rb +56 -0
  14. data/app/commands/decidim/budgets/cancel_order.rb +36 -0
  15. data/app/commands/decidim/budgets/checkout.rb +34 -0
  16. data/app/commands/decidim/budgets/remove_line_item.rb +35 -0
  17. data/app/controllers/concerns/decidim/budgets/needs_current_order.rb +27 -0
  18. data/app/controllers/decidim/budgets/admin/application_controller.rb +14 -0
  19. data/app/controllers/decidim/budgets/admin/projects_controller.rb +69 -0
  20. data/app/controllers/decidim/budgets/application_controller.rb +13 -0
  21. data/app/controllers/decidim/budgets/line_items_controller.rb +43 -0
  22. data/app/controllers/decidim/budgets/orders_controller.rb +38 -0
  23. data/app/controllers/decidim/budgets/projects_controller.rb +44 -0
  24. data/app/forms/decidim/budgets/admin/project_form.rb +44 -0
  25. data/app/helpers/decidim/budgets/application_helper.rb +12 -0
  26. data/app/helpers/decidim/budgets/projects_helper.rb +29 -0
  27. data/app/models/decidim/budgets/application_record.rb +9 -0
  28. data/app/models/decidim/budgets/line_item.rb +20 -0
  29. data/app/models/decidim/budgets/order.rb +52 -0
  30. data/app/models/decidim/budgets/project.rb +15 -0
  31. data/app/services/decidim/budgets/project_search.rb +58 -0
  32. data/app/views/decidim/budgets/admin/projects/_form.html.erb +31 -0
  33. data/app/views/decidim/budgets/admin/projects/edit.html.erb +9 -0
  34. data/app/views/decidim/budgets/admin/projects/index.html.erb +27 -0
  35. data/app/views/decidim/budgets/admin/projects/new.html.erb +9 -0
  36. data/app/views/decidim/budgets/line_items/update_budget.js.erb +21 -0
  37. data/app/views/decidim/budgets/projects/_budget_confirm.html.erb +30 -0
  38. data/app/views/decidim/budgets/projects/_budget_excess.html.erb +14 -0
  39. data/app/views/decidim/budgets/projects/_budget_summary.html.erb +46 -0
  40. data/app/views/decidim/budgets/projects/_count.html.erb +1 -0
  41. data/app/views/decidim/budgets/projects/_filters.html.erb +24 -0
  42. data/app/views/decidim/budgets/projects/_linked_projects.html.erb +12 -0
  43. data/app/views/decidim/budgets/projects/_order_progress.html.erb +34 -0
  44. data/app/views/decidim/budgets/projects/_order_selected_projects.html.erb +25 -0
  45. data/app/views/decidim/budgets/projects/_order_total_budget.html.erb +1 -0
  46. data/app/views/decidim/budgets/projects/_project.html.erb +40 -0
  47. data/app/views/decidim/budgets/projects/_project_budget_button.html.erb +9 -0
  48. data/app/views/decidim/budgets/projects/_projects.html.erb +8 -0
  49. data/app/views/decidim/budgets/projects/_tags.html.erb +10 -0
  50. data/app/views/decidim/budgets/projects/index.html.erb +26 -0
  51. data/app/views/decidim/budgets/projects/index.js.erb +2 -0
  52. data/app/views/decidim/budgets/projects/show.html.erb +48 -0
  53. data/config/i18n-tasks.yml +4 -0
  54. data/config/locales/ca.yml +84 -0
  55. data/config/locales/en.yml +95 -0
  56. data/config/locales/es.yml +84 -0
  57. data/db/migrate/20170127114122_create_projects.rb +15 -0
  58. data/db/migrate/20170130095615_create_orders.rb +13 -0
  59. data/db/migrate/20170130101825_create_line_items.rb +10 -0
  60. data/lib/decidim/budgets/admin.rb +9 -0
  61. data/lib/decidim/budgets/admin_engine.rb +22 -0
  62. data/lib/decidim/budgets/feature.rb +59 -0
  63. data/lib/decidim/budgets/list_engine.rb +30 -0
  64. data/lib/decidim/budgets/test/factories.rb +43 -0
  65. data/lib/decidim/budgets.rb +11 -0
  66. metadata +210 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: aa8f0db3125a7ddb93f9076d6e4fff7256cb1934
4
+ data.tar.gz: 109c2f3e91977e116a7d5baccf9fa142a78e100f
5
+ SHA512:
6
+ metadata.gz: 673eb952dde2972556bdcb286255d7a456f9f738764901f0c832adea7b8ea3d606b248cf4f6a33fc166ef4ed21b95f53c71d4f112745be53228e445acb7f04fd
7
+ data.tar.gz: 4e22d0bb6a0acc9a3c8820ef305eefb3a273521063908895e84f0b6a2c65c9a692e05986047949c5faaa54e396e2c9c522642be4e331d869552cfd7e215a8779
data/README.md ADDED
@@ -0,0 +1,23 @@
1
+ # Decidim::Budgets
2
+ The Budgets module adds projects to any participatory process. It adds a CRUD engine to the admin and public views scoped inside the participatory process. Projects will link to related proposals and have a budget. The users should be able to distribute a budget between these projects.
3
+
4
+ ## Usage
5
+ Budgets will be available as a Feature for a Participatory Process.
6
+
7
+ ## Installation
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem 'decidim-budgets
12
+ ```
13
+
14
+ And then execute:
15
+ ```bash
16
+ $ bundle
17
+ ```
18
+
19
+ ## Contributing
20
+ See [Decidim](https://github.com/AjuntamentdeBarcelona/decidim).
21
+
22
+ ## License
23
+ See [Decidim](https://github.com/AjuntamentdeBarcelona/decidim).
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ # frozen_string_literal: true
2
+ require "decidim/dev/common_rake"
@@ -0,0 +1 @@
1
+ //= link decidim/budgets/projects.js
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8">
2
+ <path d="M2 0v1h-.75c-.68 0-1.25.57-1.25 1.25v.5c0 .68.44 1.24 1.09 1.41l2.56.66c.14.04.34.29.34.44v.5c0 .14-.11.25-.25.25h-2.5c-.12 0-.21-.04-.25-.06v-.94h-1v1c0 .34.2.63.44.78.23.16.52.22.81.22h.75v1h1v-1h.75c.69 0 1.25-.56 1.25-1.25v-.5c0-.68-.44-1.24-1.09-1.41l-2.56-.66c-.14-.04-.34-.29-.34-.44v-.5c0-.14.11-.25.25-.25h2.5c.11 0 .21.04.25.06v.94h1v-1c0-.34-.2-.63-.44-.78-.23-.16-.52-.22-.81-.22h-.75v-1h-1z"
3
+ transform="translate(1)" />
4
+ </svg>
@@ -0,0 +1,28 @@
1
+ // = require_self
2
+
3
+ $(() => {
4
+ const $projects = $('#projects, #project');
5
+ const $budgetSummaryTotal = $('.budget-summary__total');
6
+ const $budgetExceedModal = $('#budget-excess');
7
+
8
+ const totalBudget = $budgetSummaryTotal.data('total-budget');
9
+
10
+ const cancelEvent = (event) => {
11
+ event.stopPropagation();
12
+ event.preventDefault();
13
+ };
14
+
15
+ $projects.on('click', '.budget--list__action', (event) => {
16
+ const currentBudget = $('.budget-summary__progressbox').data('current-budget');
17
+ const $currentTarget = $(event.currentTarget);
18
+ const projectBudget = $currentTarget.data('budget');
19
+
20
+ if ($currentTarget.attr('disabled')) {
21
+ cancelEvent(event);
22
+
23
+ } else if ($currentTarget.data('add') && ((currentBudget + projectBudget) > totalBudget)) {
24
+ $budgetExceedModal.foundation('toggle');
25
+ cancelEvent(event);
26
+ }
27
+ });
28
+ });
@@ -0,0 +1 @@
1
+ @import "budget/*";
@@ -0,0 +1,32 @@
1
+ .budget-list__title{
2
+ @include breakpoint(smallmedium down){
3
+ font-size: $global-font-size;
4
+ }
5
+ }
6
+ .budget-list__data{
7
+ flex-basis: 9rem;
8
+ @include breakpoint(medium){
9
+ flex-direction: row;
10
+ flex-basis: 16rem;
11
+ }
12
+ }
13
+ .budget-list__data--added{
14
+ background-color: mix(white, $success, 80%);
15
+ }
16
+
17
+ .budget-list__number{
18
+ @include breakpoint(medium down){
19
+ font-size: 1rem;
20
+ }
21
+ @include breakpoint(medium){
22
+ flex-grow: 1;
23
+ font-size: 1.5rem;
24
+ margin-right: 1rem;
25
+ margin-bottom: 0;
26
+ text-align: right;
27
+ }
28
+ }
29
+
30
+ .budget--list__action{
31
+ margin-bottom: 0;
32
+ }
@@ -0,0 +1,78 @@
1
+ .budget-summary__total{
2
+ margin-bottom: .5rem;
3
+ }
4
+
5
+ .budget-summary__progressbox{
6
+ align-items: stretch;
7
+ margin-bottom: .5rem;
8
+ @include breakpoint(smallmedium down){
9
+ text-align: center;
10
+ }
11
+ @include breakpoint(medium){
12
+ display: flex;
13
+ }
14
+ .button{
15
+ margin-bottom: 0;
16
+ }
17
+ }
18
+
19
+ .progressbox-fixed-wrapper{
20
+ position: fixed;
21
+ top: 0;
22
+ left: 0;
23
+ right: 0;
24
+ z-index: 2;
25
+ background: $white;
26
+ box-shadow: 0 2px 7px rgba(black,.1);
27
+ display: none;
28
+ &.is-progressbox-visible{
29
+ display: block;
30
+ }
31
+
32
+ }
33
+
34
+ .budget-summary__progressbox--fixed{
35
+ margin: auto;
36
+ max-width: $global-width;
37
+ padding: 1rem 2rem;
38
+ @include breakpoint(mediumlarge){
39
+ padding: 1rem 4rem;
40
+ }
41
+ display: flex;
42
+ }
43
+
44
+ .budget-progress{
45
+ flex-grow: 1;
46
+ margin-bottom: .5rem;
47
+ min-height: 1.5rem;
48
+ @include breakpoint(medium){
49
+ min-height: 2rem;
50
+ margin-bottom: 0;
51
+ margin-right: 1rem;
52
+ }
53
+ }
54
+
55
+ .budget-progress--fixed{
56
+ min-height: 2rem;
57
+ margin-bottom: 0;
58
+ margin-right: 1rem;
59
+ }
60
+
61
+
62
+ .budget-progress__meter{
63
+ min-width: 0.1%;
64
+ }
65
+
66
+ .budget-summary__selected{
67
+ border-top: $border;
68
+ padding-top: .5rem;
69
+ padding-bottom: .5rem;
70
+ }
71
+
72
+ .budget-summary__selected-list{
73
+ margin-top: 2rem;
74
+ }
75
+
76
+ .budget-summary__selected-number{
77
+ margin: 0 .5rem;
78
+ }
@@ -0,0 +1,17 @@
1
+ //Foundation progress extension
2
+ .progress{
3
+ position: relative;
4
+ }
5
+ .progress-meter--minimum{
6
+ background: repeating-linear-gradient(-55deg, rgba(white, 0.2), rgba(white, 0.2) 8px, rgba(black, 0.03) 8px, rgba(black, 0.03) 16px);
7
+ position: absolute;
8
+ }
9
+
10
+ .progress-meter-text--right{
11
+ left: auto;
12
+ min-width: 100%;
13
+ transform: translate(0, -50%);
14
+ text-align: right;
15
+ padding-left: 1rem;
16
+ padding-right: .5rem;
17
+ }
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+ module Decidim
3
+ module Budgets
4
+ # A command with all the business to add new line items to orders
5
+ class AddLineItem < Rectify::Command
6
+ # Public: Initializes the command.
7
+ #
8
+ # order - The current order for the user or nil if it is not created yet.
9
+ # project - The the project to include in the order
10
+ # current_user - The current user logged in
11
+ def initialize(current_order, project, current_user)
12
+ @order = current_order
13
+ @project = project
14
+ @current_user = current_user
15
+ end
16
+
17
+ # Executes the command. Broadcasts these events:
18
+ #
19
+ # - :ok when everything is valid.
20
+ # - :invalid if the there is an error.
21
+ #
22
+ # Returns nothing.
23
+ def call
24
+ transaction do
25
+ return broadcast(:invalid) if order.checked_out?
26
+ add_line_item
27
+ broadcast(:ok, order)
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def order
34
+ @order ||= Order.create!(user: @current_user, feature: @project.feature)
35
+ end
36
+
37
+ def add_line_item
38
+ order.projects << @project
39
+ order.save!
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+ module Decidim
3
+ module Budgets
4
+ module Admin
5
+ # This command is executed when the user creates a Project from the admin
6
+ # panel.
7
+ class CreateProject < Rectify::Command
8
+ def initialize(form)
9
+ @form = form
10
+ end
11
+
12
+ # Creates the project if valid.
13
+ #
14
+ # Broadcasts :ok if successful, :invalid otherwise.
15
+ def call
16
+ return broadcast(:invalid) if @form.invalid?
17
+
18
+ transaction do
19
+ create_project
20
+ link_proposals
21
+ end
22
+
23
+ broadcast(:ok)
24
+ end
25
+
26
+ private
27
+
28
+ attr_reader :project
29
+
30
+ def create_project
31
+ @project = Project.create!(
32
+ scope: @form.scope,
33
+ category: @form.category,
34
+ feature: @form.current_feature,
35
+ title: @form.title,
36
+ short_description: @form.short_description,
37
+ description: @form.description,
38
+ budget: @form.budget
39
+ )
40
+ end
41
+
42
+ def proposals
43
+ @proposals ||= project.sibling_scope(:proposals).where(id: @form.proposal_ids)
44
+ end
45
+
46
+ def link_proposals
47
+ project.link_resources(proposals, "included_proposals")
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+ module Decidim
3
+ module Budgets
4
+ module Admin
5
+ # This command is executed when the user changes a Project from the admin
6
+ # panel.
7
+ class UpdateProject < Rectify::Command
8
+ # Initializes an UpdateProject Command.
9
+ #
10
+ # form - The form from which to get the data.
11
+ # project - The current instance of the project to be updated.
12
+ def initialize(form, project)
13
+ @form = form
14
+ @project = project
15
+ end
16
+
17
+ # Updates the project if valid.
18
+ #
19
+ # Broadcasts :ok if successful, :invalid otherwise.
20
+ def call
21
+ return broadcast(:invalid) if form.invalid?
22
+
23
+ transaction do
24
+ update_project
25
+ link_proposals
26
+ end
27
+
28
+ broadcast(:ok)
29
+ end
30
+
31
+ private
32
+
33
+ attr_reader :project, :form
34
+
35
+ def update_project
36
+ project.update_attributes!(
37
+ scope: form.scope,
38
+ category: form.category,
39
+ title: form.title,
40
+ short_description: form.short_description,
41
+ description: form.description,
42
+ budget: form.budget
43
+ )
44
+ end
45
+
46
+ def proposals
47
+ @proposals ||= project.sibling_scope(:proposals).where(id: form.proposal_ids)
48
+ end
49
+
50
+ def link_proposals
51
+ project.link_resources(proposals, "included_proposals")
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+ module Decidim
3
+ module Budgets
4
+ # A command with all the business to cancel an order.
5
+ class CancelOrder < Rectify::Command
6
+ # Public: Initializes the command.
7
+ #
8
+ # order - The current order for the user.
9
+ def initialize(order)
10
+ @order = order
11
+ end
12
+
13
+ # Executes the command. Broadcasts these events:
14
+ #
15
+ # - :ok when everything is valid.
16
+ # - :invalid if the there is an error.
17
+ #
18
+ # Returns nothing.
19
+ def call
20
+ return broadcast(:invalid) if invalid_order?
21
+ cancel_order!
22
+ broadcast(:ok, @order)
23
+ end
24
+
25
+ private
26
+
27
+ def invalid_order?
28
+ !@order&.checked_out?
29
+ end
30
+
31
+ def cancel_order!
32
+ @order.destroy!
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+ module Decidim
3
+ module Budgets
4
+ # A command with all the business to checkout.
5
+ class Checkout < Rectify::Command
6
+ # Public: Initializes the command.
7
+ #
8
+ # order - The current order for the user.
9
+ # feature - The current feature.
10
+ def initialize(order, feature)
11
+ @order = order
12
+ @feature = feature
13
+ end
14
+
15
+ # Executes the command. Broadcasts these events:
16
+ #
17
+ # - :ok when everything is valid.
18
+ # - :invalid if the there is an error.
19
+ #
20
+ # Returns nothing.
21
+ def call
22
+ return broadcast(:invalid) unless @order&.can_checkout?
23
+ checkout!
24
+ broadcast(:ok, @order)
25
+ end
26
+
27
+ private
28
+
29
+ def checkout!
30
+ @order.update_attributes!(checked_out_at: Time.current)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+ module Decidim
3
+ module Budgets
4
+ # A command with all the business to add remove line items from orders
5
+ class RemoveLineItem < Rectify::Command
6
+ # Public: Initializes the command.
7
+ #
8
+ # order - The current order for the user
9
+ # project - The the project to remove from the order
10
+ def initialize(order, project)
11
+ @order = order
12
+ @project = project
13
+ end
14
+
15
+ # Executes the command. Broadcasts these events:
16
+ #
17
+ # - :ok when everything is valid.
18
+ # - :invalid if the there is an error.
19
+ #
20
+ # Returns nothing.
21
+ def call
22
+ return broadcast(:invalid) if @order.checked_out?
23
+ remove_line_item
24
+ broadcast(:ok, @order)
25
+ end
26
+
27
+ private
28
+
29
+ def remove_line_item
30
+ @order.projects.destroy(@project)
31
+ @order.save!
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/concern"
4
+
5
+ module Decidim
6
+ module Budgets
7
+ # Shared behaviour for controllers that need the current order to be present.
8
+ module NeedsCurrentOrder
9
+ extend ActiveSupport::Concern
10
+
11
+ included do
12
+ helper_method :current_order
13
+
14
+ # The current order created by the user.
15
+ #
16
+ # Returns an Order.
17
+ def current_order
18
+ @current_order ||= Order.includes(:projects).find_by(user: current_user, feature: current_feature)
19
+ end
20
+
21
+ def current_order=(order)
22
+ @current_order = order
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+ module Decidim
3
+ module Budgets
4
+ module Admin
5
+ # This controller is the abstract class from which all other controllers of
6
+ # this engine inherit.
7
+ #
8
+ # Note that it inherits from `Decidim::Features::BaseController`, which
9
+ # override its layout and provide all kinds of useful methods.
10
+ class ApplicationController < Decidim::Admin::Features::BaseController
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+ module Decidim
3
+ module Budgets
4
+ module Admin
5
+ # This controller allows an admin to manage projects from a Participatory Process
6
+ class ProjectsController < Admin::ApplicationController
7
+ helper_method :projects
8
+
9
+ def new
10
+ @form = form(ProjectForm).instance
11
+ end
12
+
13
+ def create
14
+ @form = form(ProjectForm).from_params(params)
15
+
16
+ CreateProject.call(@form) do
17
+ on(:ok) do
18
+ flash[:notice] = I18n.t("projects.create.success", scope: "decidim.budgets.admin")
19
+ redirect_to projects_path
20
+ end
21
+
22
+ on(:invalid) do
23
+ flash.now[:alert] = I18n.t("projects.create.invalid", scope: "decidim.budgets.admin")
24
+ render action: "new"
25
+ end
26
+ end
27
+ end
28
+
29
+ def edit
30
+ @form = form(ProjectForm).from_model(project)
31
+ end
32
+
33
+ def update
34
+ @form = form(ProjectForm).from_params(params)
35
+
36
+ UpdateProject.call(@form, project) do
37
+ on(:ok) do
38
+ flash[:notice] = I18n.t("projects.update.success", scope: "decidim.budgets.admin")
39
+ redirect_to projects_path
40
+ end
41
+
42
+ on(:invalid) do
43
+ flash.now[:alert] = I18n.t("projects.update.invalid", scope: "decidim.budgets.admin")
44
+ render action: "edit"
45
+ end
46
+ end
47
+ end
48
+
49
+ def destroy
50
+ project.destroy!
51
+
52
+ flash[:notice] = I18n.t("projects.destroy.success", scope: "decidim.budgets.admin")
53
+
54
+ redirect_to projects_path
55
+ end
56
+
57
+ private
58
+
59
+ def projects
60
+ @projects ||= Project.where(feature: current_feature)
61
+ end
62
+
63
+ def project
64
+ @project ||= projects.find(params[:id])
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Budgets
5
+ # This controller is the abstract class from which all other controllers of
6
+ # this engine inherit.
7
+ #
8
+ # Note that it inherits from `Decidim::Components::BaseController`, which
9
+ # override its layout and provide all kinds of useful methods.
10
+ class ApplicationController < Decidim::Features::BaseController
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Budgets
5
+ # Exposes the line items resource so users can create and remove from orders.
6
+ class LineItemsController < Decidim::Budgets::ApplicationController
7
+ include NeedsCurrentOrder
8
+
9
+ helper_method :project
10
+
11
+ def create
12
+ AddLineItem.call(current_order, project, current_user) do
13
+ on(:ok) do |order|
14
+ self.current_order = order
15
+ render "update_budget"
16
+ end
17
+
18
+ on(:invalid) do
19
+ render nothing: true, status: 422
20
+ end
21
+ end
22
+ end
23
+
24
+ def destroy
25
+ RemoveLineItem.call(current_order, project) do
26
+ on(:ok) do |_order|
27
+ render "update_budget"
28
+ end
29
+
30
+ on(:invalid) do
31
+ render nothing: true, status: 422
32
+ end
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def project
39
+ @project ||= Project.where(id: params[:project_id], feature: current_feature).first
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Budgets
5
+ # Exposes the order resource so users can checkout it.
6
+ class OrdersController < Decidim::Budgets::ApplicationController
7
+ include NeedsCurrentOrder
8
+
9
+ def checkout
10
+ Checkout.call(current_order, current_feature) do
11
+ on(:ok) do
12
+ flash[:notice] = I18n.t("orders.checkout.success", scope: "decidim")
13
+ redirect_to projects_path
14
+ end
15
+
16
+ on(:invalid) do
17
+ flash.now[:alert] = I18n.t("orders.checkout.error", scope: "decidim")
18
+ redirect_to projects_path
19
+ end
20
+ end
21
+ end
22
+
23
+ def destroy
24
+ CancelOrder.call(current_order) do
25
+ on(:ok) do
26
+ flash[:notice] = I18n.t("orders.destroy.success", scope: "decidim")
27
+ redirect_to projects_path
28
+ end
29
+
30
+ on(:invalid) do
31
+ flash.now[:alert] = I18n.t("orders.destroy.error", scope: "decidim")
32
+ redirect_to projects_path
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end