Skip to content

Differentiate individual and enterprise on customers#14294

Open
pacodelaluna wants to merge 8 commits into
openfoodfoundation:masterfrom
pacodelaluna:differentiate-individual-and-enterprise-on-customers
Open

Differentiate individual and enterprise on customers#14294
pacodelaluna wants to merge 8 commits into
openfoodfoundation:masterfrom
pacodelaluna:differentiate-individual-and-enterprise-on-customers

Conversation

@pacodelaluna

@pacodelaluna pacodelaluna commented May 17, 2026

Copy link
Copy Markdown
Contributor

⚠️ Use # 88 B2B customer on clockify to work on this

What? Why?

What should we test?

  1. Log in as enterprise
  2. Notice you can add enterprise type to customers, but the columns are hidden by default
  3. Check the mandatory fields
  4. Check invoices
  5. Check the API V1 customer endpoint has been updated as well

Release notes

  • Add the ability to differentiate between enterprise and individuals in admin/customers

Changelog Category (reviewers may add a label for the release notes):

  • User facing changes
  • API changes (V0, V1, DFC or Webhook)
  • Technical changes only
  • Feature toggled

The title of the pull request will be included in the release notes.

@github-project-automation github-project-automation Bot moved this to All the things 💤 in OFN Delivery board May 17, 2026
@pacodelaluna pacodelaluna marked this pull request as draft May 17, 2026 22:05
@sigmundpetersen sigmundpetersen moved this from All the things 💤 to In Progress ⚙ in OFN Delivery board May 18, 2026
@pacodelaluna pacodelaluna force-pushed the differentiate-individual-and-enterprise-on-customers branch 2 times, most recently from 9171071 to 5fffb5a Compare June 10, 2026 16:01
@pacodelaluna pacodelaluna force-pushed the differentiate-individual-and-enterprise-on-customers branch 4 times, most recently from 9ec7e68 to 74980c4 Compare June 10, 2026 17:46
@pacodelaluna pacodelaluna force-pushed the differentiate-individual-and-enterprise-on-customers branch from 74980c4 to f11746e Compare June 10, 2026 20:49

@pacodelaluna pacodelaluna left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I finished a first iteration on this topic, I put some comments, there must be some adjustments. I will add screenshots below.

Comment thread app/models/customer.rb
enum :customer_type, {
individual: "individual",
enterprise: "enterprise"
}, default: "individual"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Using an enum for our purpose, it seems a good fit.

Comment thread app/models/customer.rb

attr_accessor :gateway_recurring_payment_client_secret, :gateway_shop_id

attribute :enterprise_charges_sales_tax, :boolean, default: false

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The enterprise_charges_sales_tax field is handled with a checkbox input on the form, so the presence validation is an issue, as the checkbox can be empty. I choose the approach of giving it a default value. Tell me if you prefer an other approach.

= @order.customer.email
- if @order&.customer&.enterprise_acn.present?
%br
= @order.customer.enterprise_acn

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I didn't have mockups, so I put the enterprise_acn at the end of the customer details, tell me if it has to be in an other position.

code { SecureRandom.base64(150) }
user
bill_address { create(:address) }
customer_type { "individual" }

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We have a default value now, but I kept this here, as a kind of documentation. I can remove it if it does not make sense.

expect(presenter.enterprise_name).to be_nil
end
end
end

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This class was not tested, so I added them, but I am wondering if they are really useful.

expect(json['data']['attributes']['email']).to eq(customer.email)
end
end
end

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Same here, not sure these tests are much important, I added them a bit by reflex.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks, I guess that most of this is already covered by spec/requests/api/v1/customers_spec.rb.

@pacodelaluna pacodelaluna marked this pull request as ready for review June 10, 2026 21:02
@pacodelaluna

Copy link
Copy Markdown
Contributor Author

The failing check seems to be a flaky test, not related to my changes.

@pacodelaluna

Copy link
Copy Markdown
Contributor Author

On the customers list:
image

On the invoice:
image

@pacodelaluna

Copy link
Copy Markdown
Contributor Author

It makes me think that we may need to adjust enterprise data in our Anonymization task, it looks like we are missing some parts on this side. I will take a look after this.

@sigmundpetersen sigmundpetersen moved this from In Progress ⚙ to Code review 🔎 in OFN Delivery board Jun 11, 2026

@rioug rioug left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Looks good, thanks for adding the extra tests !

@rioug rioug added api changes These pull requests change the API and can break integrations user facing changes Thes pull requests affect the user experience labels Jun 12, 2026
@dacook dacook self-requested a review June 15, 2026 04:40

@dacook dacook left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Great job, this looks mostly good.
I have a small suggested change to simplify the code, and I suggest using DB enums but would be happy if you don't have time to try it.

In reviewing this, I also needed to consider the bigger picture and added some comments on the issue. I'm not a fan of the field name enterprise_acn.
But I'm not exactly sure of the best option, so am interested to hear other ideas. If "acn" is agreed, I will approve it :)

class AddEnterpriseRelatedFieldsToCustomers < ActiveRecord::Migration[7.1]
def change
change_table :customers, bulk: true do |t|
t.string :customer_type, default: "individual", null: false

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This will store a string for every record. We could instead make use of database-level enums which would be more efficient:
https://guides.rubyonrails.org/active_record_postgresql.html#enumerated-types

Would you be willing to try this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Sure, I will implement it.

Comment thread app/models/customer.rb
}
validates :customer_type,
presence: true,
inclusion: { in: customer_types.keys }

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

± It looks like you don't need to create this validation, you can just enable it on the enum definition above with validate: true
(https://stackoverflow.com/a/77025739/421243)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I tried this method initially, but I faced an issue, I don't remember exactly which one... I will try again and spot it if it pops again.

Comment thread app/models/customer.rb
expect(json['data']['attributes']['email']).to eq(customer.email)
end
end
end

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks, I guess that most of this is already covered by spec/requests/api/v1/customers_spec.rb.

@github-project-automation github-project-automation Bot moved this from Code review 🔎 to In Progress ⚙ in OFN Delivery board Jun 15, 2026
@pacodelaluna

Copy link
Copy Markdown
Contributor Author

@dacook Thanks for your review!

About spec/requests/api/v1/customers_spec.rb spec, I understand, I will remove these specs then.

About the enterprise_acn naming, I just reuse the naming from Enterprise data model, maybe we could just put enterprise_vat_number instead? I am open to any clearer suggestion.

@dacook

dacook commented Jun 15, 2026

Copy link
Copy Markdown
Member

Thanks Paco. I'm still not sure of the best name for the field, but I don't want to hold things up further so I'm happy to approve it as-is (once you have tried the other changes).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api changes These pull requests change the API and can break integrations user facing changes Thes pull requests affect the user experience

Projects

Status: In Progress ⚙

Development

Successfully merging this pull request may close these issues.

Add the ability to differentiate between enterprise and individuals in admin/customers

4 participants