Skip to content
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

OBDS-129 Add import trigger for location groups, locations, organizat… #3078

Merged
merged 10 commits into from
Apr 6, 2022

Conversation

awalkowiak
Copy link
Collaborator

…ions, bin locations, categories and products with GET /api/loadData

…ions, bin locations, categories and products with GET /api/loadData
@awalkowiak awalkowiak added status: work in progress For issues or pull requests that are in progress but not yet completed warn: do not merge Marks a pull request that is not yet ready to be merged labels Mar 29, 2022
Copy link
Member

@jmiranda jmiranda left a comment

Choose a reason for hiding this comment

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

Where did this data come from?

@@ -1209,7 +1209,7 @@ openboxes.typeahead.delay = 300
openboxes.typeahead.minLength = 3

// Allow system administrators to disable refresh on startup
openboxes.refreshAnalyticsDataOnStartup.enabled = true
openboxes.refreshAnalyticsDataOnStartup.enabled = false
Copy link
Member

Choose a reason for hiding this comment

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

What is the reason for disabling this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@jmiranda this was a suggestion for development purposes. This is the WIP version, and @hdsldv will remove it in the final version

Copy link

Choose a reason for hiding this comment

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

reverted

Copy link
Member

Choose a reason for hiding this comment

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

@awalkowiak @hdsldv no worries. i was just wondering if there was some kind of conflict with the changes we were making.

A better approach for local development environments would be to create ~/.grails/openboxes-config.groovy and add the property there.

@@ -1804,6 +1804,45 @@ openboxes.configurationWizard.listOfDemoData = [
"<ul>",
]

openboxes.configurationWizard.dataInit = [
Copy link
Member

Choose a reason for hiding this comment

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

Can we convert this to Groovy DSL syntax

openboxes.configuration.data { 
    locations { 
        enabled = true
        url = 
    }
    ...
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yup, agree. I gave the same suggestion.

Copy link

Choose a reason for hiding this comment

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

done

Copy link

Choose a reason for hiding this comment

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

I reverted change to DSL as I was not able to use it as key-value map

Copy link
Member

Choose a reason for hiding this comment

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

Sorry I screwed that up. It should probably look something like this.

openboxes { 
    configuration { 
        data { 
            locations { 
                enabled = true 
                url = "<whatever>"
            } 
            ...
        } 
    } 
}

Copy link

Choose a reason for hiding this comment

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

It works, thanks

@@ -60,6 +60,11 @@ class UrlMappings {
}


"/api/loadData"(parseRequest: true) {
Copy link
Member

Choose a reason for hiding this comment

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

Let's make this more REST-like And we need to do some thinking about naming convention here.

Something like this maybe

GET /api/config/data/demo

But I'll do some more thinking about this tomorrow.

Copy link

Choose a reason for hiding this comment

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

For now changed to /api/config/data/demo

@@ -1345,4 +1345,25 @@ class ProductService {
importProducts(products)
}
}

ProductCatalogItem createOrUpdateProductCatalogItem(Map params) {
Copy link
Member

Choose a reason for hiding this comment

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

Move this to a new ProductCatalogService.

Copy link

Choose a reason for hiding this comment

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

done

import org.pih.warehouse.importer.ImportDataCommand
import org.pih.warehouse.product.ProductCatalog

class LoadDataService {
Copy link
Member

Choose a reason for hiding this comment

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

I think these methods should go into DataService.

Copy link

Choose a reason for hiding this comment

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

I do not think it is possible. LoadDataService requires productService, which requires dataService. After moving to DataService there is creating bean exception, because of circular reference between DataService and ProductService

@ghost
Copy link

ghost commented Mar 30, 2022

Where did this data come from?

@jmiranda If you have csv files in mind, they are linked in ticket description (except categories which is copy of UNSPSC_categories.csv). I converted them from excel to csv format


User user = new User(
username: attr.username,
password: attr.username, // FIXME: What is default password?
Copy link
Member

Choose a reason for hiding this comment

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

Oh yeah this doesn't feel right. I don't know if we want to be setting a password at all. I think we might need to do some type of activation here. But we should have a discussion with Kelsey about expected behaviors. This could be a huge security hole.

Copy link

Choose a reason for hiding this comment

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

I added active: false for imported users as password has blank: false constraint

userRoles.add(role)
}

if (User.findByUsername(attr.username)) {
Copy link
Member

Choose a reason for hiding this comment

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

This should be already handled through the unique constraint on the User domain.

Copy link
Member

Choose a reason for hiding this comment

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

You just need to check if the save was successful and throw an exception if not.

// The hasErrors checks whether there were errors when data binding
if (user.hasErrors() || !user.save()) { 
    throw new ValidationException("invalid user", user.errors)
}

Or you can explcitly validate the domain before saving.

user.validate() 
if (user.hasErrors() || !user.save()) { 
    throw new ValidationException("invalid user", user.errors)
}

I prefer the first approach.

Copy link

Choose a reason for hiding this comment

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

Added failOnError when saving user

if (!role) {
role = new Role(
roleType: roleType,
name: roleType.toString(),
Copy link
Member

Choose a reason for hiding this comment

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

You should use roleType.name() instead of roleType.toString() to prevent any weirdness with the implicit toString().

https://stackoverflow.com/questions/6667243/using-enum-values-as-string-literals

However, I don't think we want to be creating new system roles during import unless it's explicitly stated in the requirements. I'd rather throw an exception stating that a role with role type doesn't exist. There's also a case where one role type might be mapped to multiple roles. Not sure how we want to handle that. Probably throw an exception for that as well.

Note, once you add a role to the userRoles set, nothing else happens so all of this role / user role logic is basically a no-op as the user roles won't be persisted to the database.

Instead, you probably want to use user.addToUserRoles().

for (RoleType roleType in roleTypes) {
    Role role = Role.findByRoleType(roleType)
    if (!role) throw new IllegalArgumentException("Role for role type ${roleType.name()} does not exist")
    user.addToUserRoles(new UserRole(user: user, role: role))
}

One caveat is that we probably need to save the user before we process the roles.

Copy link

Choose a reason for hiding this comment

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

Now null role throws exception. I'm not sure what you mean by no-op - I'm assigning userRoles set to roles property and it works just fine - user and corresponding user_role records are created

@awalkowiak
Copy link
Collaborator Author

awalkowiak commented Apr 6, 2022

Since the majority of work was done and only fixes to the product supplier are the remaining part to be done here, I am gonna merge this one to unblock other work. I'll create a ticket for improvements and put it in the next sprint.

Side note, the issues related to the product supplier import might be related to #3049

cc @jmiranda @hdsldv

@awalkowiak awalkowiak merged commit 4dff766 into develop Apr 6, 2022
@awalkowiak awalkowiak deleted the OBDS-129 branch April 6, 2022 14:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: work in progress For issues or pull requests that are in progress but not yet completed warn: do not merge Marks a pull request that is not yet ready to be merged
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants