-
-
Notifications
You must be signed in to change notification settings - Fork 403
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
Conversation
…ions, bin locations, categories and products with GET /api/loadData
grails-app/controllers/org/pih/warehouse/api/LoadDataApiController.groovy
Outdated
Show resolved
Hide resolved
grails-app/services/org/pih/warehouse/data/LoadDataService.groovy
Outdated
Show resolved
Hide resolved
There was a problem hiding this 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?
grails-app/conf/Config.groovy
Outdated
@@ -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 |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reverted
There was a problem hiding this comment.
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.
grails-app/conf/Config.groovy
Outdated
@@ -1804,6 +1804,45 @@ openboxes.configurationWizard.listOfDemoData = [ | |||
"<ul>", | |||
] | |||
|
|||
openboxes.configurationWizard.dataInit = [ |
There was a problem hiding this comment.
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 =
}
...
}
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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>"
}
...
}
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It works, thanks
grails-app/conf/UrlMappings.groovy
Outdated
@@ -60,6 +60,11 @@ class UrlMappings { | |||
} | |||
|
|||
|
|||
"/api/loadData"(parseRequest: true) { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
…ET /api/loadData to /api/config/data/demo
@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? |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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)) { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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(), |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
… default + prevent adding users with non-existing role type
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 |
…ions, bin locations, categories and products with GET /api/loadData