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

OBPIH-5455 Add filter for GL account #3866

Merged
merged 15 commits into from
Mar 1, 2023
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions grails-app/conf/UrlMappings.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -49,22 +49,28 @@ class UrlMappings {

// Category options for filters on product list page
"/api/categoryOptions"(parseRequest: true) {
controller = { "productApi" }
controller = { "selectOptionsApi" }
action = [GET: "categoryOptions"]
}

// Catalog options for filters on product list page
"/api/catalogOptions"(parseRequest: true) {
controller = { "productApi" }
controller = { "selectOptionsApi" }
action = [GET: "catalogOptions"]
}

// Tag options for filters on product list page
"/api/tagOptions"(parseRequest: true) {
controller = { "productApi" }
controller = { "selectOptionsApi" }
action = [GET: "tagOptions"]
}

// Gl account options for filters on product list page
"/api/glAccountOptions"(parseRequest: true) {
controller = { "selectOptionsApi" }
action = [GET: "glAccountOptions"]
}

"/api/products"(parseRequest: true) {
controller = { "productApi" }
action = [GET: "list"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
package org.pih.warehouse.api

import grails.converters.JSON
import org.pih.warehouse.core.GlAccount
import org.pih.warehouse.core.Location
import org.pih.warehouse.core.Tag
import org.pih.warehouse.product.Category
Expand All @@ -32,6 +33,7 @@ class ProductApiController extends BaseDomainApiController {
def categories = params.categoryId ? Category.findAllByIdInList(params.list("categoryId")) : null
def tags = params.tagId ? Tag.getAll(params.list("tagId")) : []
def catalogs = params.catalogId ? ProductCatalog.getAll(params.list("catalogId")) : []
def glAccounts = params.glAccountsId ? GlAccount.getAll(params.list('glAccountsId')) : []

// Following this approach of assigning q into other params for productService.getProducts
params.name = params.q
Expand All @@ -49,7 +51,7 @@ class ProductApiController extends BaseDomainApiController {
params.max = -1
}

def products = productService.getProducts(categories, catalogs, tags, includeInactive, params)
def products = productService.getProducts(categories, catalogs, tags, glAccounts, includeInactive, params)

if (params.format == 'csv') {
boolean includeAttributes = params.boolean("includeAttributes") ?: false
Expand Down Expand Up @@ -262,29 +264,4 @@ class ProductApiController extends BaseDomainApiController {
def demand = forecastingService.getDemand(origin, destination, product)
render([monthlyDemand: demand.monthlyDemand, quantityOnHand: quantityOnHand] as JSON)
}

def catalogOptions = {
def catalogs = ProductCatalog.list(sort: "name").collect {
[id: it.id, label: "${it.name} (${it?.productCatalogItems?.size()})"]
}

render([data: catalogs] as JSON)
}

def categoryOptions = {
def categories = Category.list().sort().collect {
[id: it.id, label: it.getHierarchyAsString(" > ")]
}

render([data: categories] as JSON)

}

def tagOptions = {
def tags = Tag.list(sort: "tag").collect {
[id: it.id, label: "${it.tag} (${it?.products?.size()})"]
}

render([data: tags] as JSON)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* Copyright (c) 2012 Partners In Health. All rights reserved.
* The use and distribution terms for this software are covered by the
* Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
* which can be found in the file epl-v10.html at the root of this distribution.
* By using this software in any fashion, you are agreeing to be bound by
* the terms of this license.
* You must not remove this notice, or any other, from this software.
**/
package org.pih.warehouse.api

import grails.converters.JSON
import org.pih.warehouse.core.SelectOptionsService

class SelectOptionsApiController {

SelectOptionsService selectOptionsService;

def glAccountOptions = {
def glAccounts = selectOptionsService.getGlAccountsOptions()
Copy link
Member

Choose a reason for hiding this comment

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

@awalkowiak What do you think about using the generic API service here?

def glAccountOptions = { 
    def glAccounts = genericApiService.getList(GlAccount.class, [:]).collect {
            [id: it.id, label: "${it.code} - ${it.name}"]
        }
    }
    render([data: glAccounts] as JSON)
}

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yes, if we can get rid of adding one another redundant service, then this should be good. cc: @alannadolny

render([data: glAccounts] as JSON)
}

def tagOptions = {
def tags = selectOptionsService.getTagsOptions()
render([data: tags] as JSON)
}

def catalogOptions = {
def catalogs = selectOptionsService.getCatalogsOptions()
render([data: catalogs] as JSON)
}

def categoryOptions = {
def categories = selectOptionsService.getCategoryOptions()
render([data: categories] as JSON)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@
* You must not remove this notice, or any other, from this software.
**/
package org.pih.warehouse.core

import grails.converters.JSON
import org.pih.warehouse.product.Product

class GlAccountController {

def index = {
redirect(action: "list", params: params)
}
Expand Down
1 change: 1 addition & 0 deletions grails-app/i18n/messages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4103,6 +4103,7 @@ react.productsList.addProduct.label=Add product
react.productsList.filters.category.label=Category
react.productsList.filters.catalog.label=Formulary
react.productsList.filters.tags.label=Tags
react.productsList.filters.glAccount.label=Gl Account
react.productsList.filters.search.placeholder.label=Search by product name
react.productsList.column.active.label=Active
react.productsList.column.code.label=Code
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* Copyright (c) 2012 Partners In Health. All rights reserved.
* The use and distribution terms for this software are covered by the
* Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
* which can be found in the file epl-v10.html at the root of this distribution.
* By using this software in any fashion, you are agreeing to be bound by
* the terms of this license.
* You must not remove this notice, or any other, from this software.
**/
package org.pih.warehouse.core

import org.pih.warehouse.product.Category
import org.pih.warehouse.product.ProductCatalog

class SelectOptionsService {

def getGlAccountsOptions() {
return GlAccount.list().collect {
[id: it.id, label: "${it.code} - ${it.name}"]
}
}

def getTagsOptions() {
return Tag.list(sort: "tag").collect {
[id: it.id, label: "${it.tag} (${it?.products?.size()})"]
}
}

def getCatalogsOptions() {
return ProductCatalog.list(sort: "name").collect {
[id: it.id, label: "${it.name} (${it?.productCatalogItems?.size()})"]
}
}

def getCategoryOptions() {
return Category.list().sort().collect {
[id: it.id, label: it.getHierarchyAsString(" > ")]
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ class ProductService {
* @return
*/
List<Product> getProducts(Category category, List<Tag> tags, boolean includeInactive, Map params) {
return getProducts([category], [], tags, includeInactive, params)
return getProducts([category], [], tags, [], includeInactive, params)
}

/**
Expand All @@ -282,10 +282,11 @@ class ProductService {
* @param category
* @param catalogs
* @param tags
* @param glAccounts
* @param params
* @return
*/
List<Product> getProducts(List<Category> categories, List<ProductCatalog> catalogsInput, List<Tag> tagsInput, boolean includeInactive, Map params) {
List<Product> getProducts(List<Category> categories, List<ProductCatalog> catalogsInput, List<Tag> tagsInput, List<GlAccount> glAccounts, boolean includeInactive, Map params) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I am starting to dislike these parameters more with each new one. I think we could think about refactoring this one.

int max = params.max ? params.int("max") : 10
int offset = params.offset ? params.int("offset") : 0
String sortColumn = params.sort ?: "name"
Expand Down Expand Up @@ -323,6 +324,11 @@ class ProductService {
}
}

if (glAccounts) {
glAccount {
'in'("id", glAccounts.collect { it.id })
}
}

if (tagsInput) {
tags {
Expand Down
6 changes: 6 additions & 0 deletions src/js/api/services/GlAccountApi.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { GL_ACCOUNTS_OPTION } from 'api/urls';
import apiClient from 'utils/apiClient';

export default {
getGlAccountOptions: () => apiClient.get(GL_ACCOUNTS_OPTION),
};
17 changes: 11 additions & 6 deletions src/js/api/urls.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,34 @@
const API = '/openboxes/api';

// PURCHASE ORDER
export const PURCHASE_ORDER_API = '/openboxes/api/purchaseOrders';
export const PURCHASE_ORDER_API = `${API}/purchaseOrders`;
export const PURCHASE_ORDER_DELETE = id => `${PURCHASE_ORDER_API}/${id}`;
export const PURCHASE_ORDER_ROLLBACK_ORDER = id => `${PURCHASE_ORDER_API}/${id}/rollback`;

// STOCK MOVEMENT
export const STOCK_MOVEMENT_API = '/openboxes/api/stockMovements';
export const STOCK_MOVEMENT_API = `${API}/stockMovements`;
export const STOCK_MOVEMENT_DELETE = id => `${STOCK_MOVEMENT_API}/${id}`;
export const STOCK_MOVEMENT_PENDING_SHIPMENT_ITEMS = `${STOCK_MOVEMENT_API}/pendingRequisitionItems`;
export const STOCK_MOVEMENT_INCOMING_ITEMS = `${STOCK_MOVEMENT_API}/shippedItems`;

// STOCK TRANSFER
export const STOCK_TRANSFER_API = '/openboxes/api/stockTransfers';
export const STOCK_TRANSFER_API = `${API}/stockTransfers`;
export const STOCK_TRANSFER_DELETE = id => `${STOCK_TRANSFER_API}/${id}`;

// INVOICE
export const INVOICE_API = '/openboxes/api/invoices';
export const INVOICE_API = `${API}/invoices`;

// PRODUCT
export const PRODUCT_API = '/openboxes/api/products';
export const PRODUCT_API = `${API}/products`;

// STOCK LIST
export const STOCKLIST_API = '/openboxes/api/stocklists';
export const STOCKLIST_API = `${API}/stocklists`;
export const STOCKLIST_EXPORT = id => `${STOCKLIST_API}/${id}/export`;
export const STOCKLIST_DELETE = id => `${STOCKLIST_API}/${id}`;
export const STOCKLIST_CLEAR = id => `${STOCKLIST_API}/${id}/clear`;
export const STOCKLIST_CLONE = id => `${STOCKLIST_API}/${id}/clone`;
export const STOCKLIST_PUBLISH = id => `${STOCKLIST_API}/${id}/publish`;
export const STOCKLIST_UNPUBLISH = id => `${STOCKLIST_API}/${id}/unpublish`;

// GL ACCOUNTS
export const GL_ACCOUNTS_OPTION = `${API}/glAccountOptions`;
23 changes: 19 additions & 4 deletions src/js/components/products/FilterFields.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,20 @@ export default {
options: categories,
}),
},
includeCategoryChildren: {
type: CheckboxField,
label: 'react.productsList.includeSubcategories.label',
defaultMessage: 'Include all products in all subcategories',
glAccountsId: {
type: FilterSelectField,
attributes: {
valueKey: 'id',
placeholder: 'react.productsList.filters.glAccount.label',
defaultPlaceholder: 'Gl Account',
multi: true,
closeMenuOnSelect: false,
blurInputOnSelect: false,
filterElement: true,
},
getDynamicAttr: ({ glAccounts }) => ({
options: glAccounts,
}),
},
catalogId: {
type: FilterSelectField,
Expand Down Expand Up @@ -66,4 +73,12 @@ export default {
filterElement: true,
},
},
includeCategoryChildren: {
type: CheckboxField,
label: 'react.productsList.includeSubcategories.label',
defaultMessage: 'Include all products in all subcategories',
attributes: {
filterElement: true,
},
},
};
6 changes: 4 additions & 2 deletions src/js/components/products/ProductsList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import useTranslation from 'hooks/useTranslation';

const ProductsList = () => {
const {
defaultFilterValues, setFilterValues, categories, catalogs, tags, filterParams,
defaultFilterValues, setFilterValues, categories, catalogs, tags, glAccounts, filterParams,
} = useProductFilters();

useTranslation('productsList', 'reactTable');
Expand All @@ -24,7 +24,9 @@ const ProductsList = () => {
defaultValues={defaultFilterValues}
setFilterParams={setFilterValues}
filterFields={filterFields}
formProps={{ categories, catalogs, tags }}
formProps={{
categories, catalogs, tags, glAccounts,
}}
/>
<ProductsListTable filterParams={filterParams} />
</div>
Expand Down
Loading