From 93dff034b2398811d2c3a52119e3b9d04537aff2 Mon Sep 17 00:00:00 2001 From: slubwama1 Date: Fri, 8 Dec 2023 21:20:43 +0300 Subject: [PATCH] U4X-263 Create stock Item Source Reference backend support --- .../api/StockManagementService.java | 12 ++- .../api/dao/StockManagementDao.java | 23 ++++-- .../stockmanagement/api/dto/StockItemDTO.java | 11 +++ .../api/impl/StockManagementServiceImpl.java | 20 ++++- .../api/jobs/StockItemImportJob.java | 21 ++++- .../stockmanagement/api/model/StockItem.java | 24 ++++++ .../api/model/StockItemReference.java | 74 ++++++++++++++++++ api/src/main/resources/liquibase.xml | 78 +++++++++++++++++++ .../module/stockmanagement/EntityUtil.java | 2 +- .../StockManagementServiceTest.java | 8 +- .../stockmanagement/api/StockItemsImport.csv | 20 ++--- .../stockmanagement/api/StockItemsImport2.csv | 10 +++ .../controller/StockItemImportController.java | 10 +-- 13 files changed, 279 insertions(+), 34 deletions(-) create mode 100644 api/src/main/java/org/openmrs/module/stockmanagement/api/model/StockItemReference.java create mode 100644 api/src/test/resources/org/openmrs/module/stockmanagement/api/StockItemsImport2.csv diff --git a/api/src/main/java/org/openmrs/module/stockmanagement/api/StockManagementService.java b/api/src/main/java/org/openmrs/module/stockmanagement/api/StockManagementService.java index 839d95a..0251300 100644 --- a/api/src/main/java/org/openmrs/module/stockmanagement/api/StockManagementService.java +++ b/api/src/main/java/org/openmrs/module/stockmanagement/api/StockManagementService.java @@ -359,11 +359,11 @@ StockInventoryResult getStockInventory(StockItemInventorySearchFilter filter, @Transactional(readOnly = true) @Authorized(value = { Privileges.APP_STOCKMANAGEMENT_STOCKITEMS }, requireAll = false) - StockItem getStockItemByDrug(Integer drugId); + List getStockItemByDrug(Integer drugId); @Transactional(readOnly = true) @Authorized(value = { Privileges.APP_STOCKMANAGEMENT_STOCKITEMS }, requireAll = false) - StockItem getStockItemByConcept(Integer conceptId); + List getStockItemByConcept(Integer conceptId); @Transactional(readOnly = true) @Authorized(value = { Privileges.APP_STOCKMANAGEMENT_STOCKITEMS }, requireAll = false) @@ -529,4 +529,12 @@ void getStockInventory(StockItemInventorySearchFi @Transactional @Authorized(Privileges.TASK_STOCKMANAGEMENT_STOCKOPERATIONS_MUTATE) StockOperationBatchNumbersDTO saveStockOperationBatchNumbers(StockOperationBatchNumbersDTO stockOperationBatchNumbers); + + @Transactional(readOnly = true) + @Authorized(Privileges.APP_STOCKMANAGEMENT_STOCKITEMS) + StockItem getStockItemByReference(StockSource stockSource, String code); + + @Transactional + @Authorized(Privileges.APP_STOCKMANAGEMENT_STOCKITEMS) + StockItemReference saveStockItemReference(StockItemReference stockItemReference); } diff --git a/api/src/main/java/org/openmrs/module/stockmanagement/api/dao/StockManagementDao.java b/api/src/main/java/org/openmrs/module/stockmanagement/api/dao/StockManagementDao.java index 4bba8d2..8b4ad8b 100644 --- a/api/src/main/java/org/openmrs/module/stockmanagement/api/dao/StockManagementDao.java +++ b/api/src/main/java/org/openmrs/module/stockmanagement/api/dao/StockManagementDao.java @@ -3264,14 +3264,13 @@ public List getStockItemPackagingUOMs(List getStockItemByDrug(Integer drugId) { + return getSession().createCriteria(StockItem.class).add(Restrictions.eq("drug.drugId", drugId)).list(); } - public StockItem getStockItemByConcept(Integer conceptId) { - return (StockItem) getSession().createCriteria(StockItem.class).add(Restrictions.isNull("drug.drugId")) - .add(Restrictions.eq("concept.conceptId", conceptId)).uniqueResult(); + public List getStockItemByConcept(Integer conceptId) { + return getSession().createCriteria(StockItem.class).add(Restrictions.isNull("drug.drugId")) + .add(Restrictions.eq("concept.conceptId", conceptId)).list(); } public StockItemPackagingUOM getStockItemPackagingUOMByConcept(Integer stockItemId, Integer conceptId) { @@ -5272,4 +5271,16 @@ public Map checkStockBatchHasTransactionsAfterOperation(Intege return mapResult; } + + public StockItemReference getStockItemByReference(StockSource stockSource, String stockReferenceCode) { + Criteria criteria = getSession().createCriteria(StockItemReference.class); + criteria.add(Restrictions.eq("referenceSource", stockSource)); + criteria.add(Restrictions.eq("stockReferenceCode", stockReferenceCode)); + return (StockItemReference) criteria.setMaxResults(1).uniqueResult(); + } + + public StockItemReference saveStockItemReference(StockItemReference stockItemReference) { + getSession().saveOrUpdate(stockItemReference); + return stockItemReference; + } } diff --git a/api/src/main/java/org/openmrs/module/stockmanagement/api/dto/StockItemDTO.java b/api/src/main/java/org/openmrs/module/stockmanagement/api/dto/StockItemDTO.java index 6f6ce59..94d1d96 100644 --- a/api/src/main/java/org/openmrs/module/stockmanagement/api/dto/StockItemDTO.java +++ b/api/src/main/java/org/openmrs/module/stockmanagement/api/dto/StockItemDTO.java @@ -4,6 +4,7 @@ import org.openmrs.Drug; import org.openmrs.module.stockmanagement.api.model.StockBatch; import org.openmrs.module.stockmanagement.api.model.StockItemPackagingUOM; +import org.openmrs.module.stockmanagement.api.model.StockItemReference; import org.openmrs.module.stockmanagement.api.model.StockSource; import java.math.BigDecimal; @@ -73,6 +74,8 @@ public class StockItemDTO { private List stockItemPackagingUOMs; + private List stockItemReferences; + private boolean voided; private Integer creator; @@ -347,6 +350,14 @@ public void setStockItemPackagingUOMs(List stockItemPa this.stockItemPackagingUOMs = stockItemPackagingUOMs; } + public List getStockItemReferences() { + return stockItemReferences; + } + + public void setStockItemReferences(List stockItemReferences) { + this.stockItemReferences = stockItemReferences; + } + public boolean getVoided() { return voided; } diff --git a/api/src/main/java/org/openmrs/module/stockmanagement/api/impl/StockManagementServiceImpl.java b/api/src/main/java/org/openmrs/module/stockmanagement/api/impl/StockManagementServiceImpl.java index de7ce34..66e0d56 100644 --- a/api/src/main/java/org/openmrs/module/stockmanagement/api/impl/StockManagementServiceImpl.java +++ b/api/src/main/java/org/openmrs/module/stockmanagement/api/impl/StockManagementServiceImpl.java @@ -2563,16 +2563,17 @@ public List getStockItems(Collection stockItemIds) { return dao.getStockItems(stockItemIds); } + public List getStockItemPackagingUOMs( List filters) { return dao.getStockItemPackagingUOMs(filters); } - public StockItem getStockItemByDrug(Integer drugId) { + public List getStockItemByDrug(Integer drugId) { return dao.getStockItemByDrug(drugId); } - public StockItem getStockItemByConcept(Integer conceptId) { + public List getStockItemByConcept(Integer conceptId) { return dao.getStockItemByConcept(conceptId); } @@ -3431,4 +3432,19 @@ public StockOperationBatchNumbersDTO saveStockOperationBatchNumbers(StockOperati return stockOperationBatchNumbers; } + + @Override + public StockItem getStockItemByReference(StockSource stockSource, String code) { + StockItemReference stockItemReference = dao.getStockItemByReference(stockSource,code); + if(stockItemReference!=null) { + return dao.getStockItemByReference(stockSource, code).getStockItem(); + } + + return null; + } + + @Override + public StockItemReference saveStockItemReference(StockItemReference stockItemReference) { + return dao.saveStockItemReference(stockItemReference); + } } diff --git a/api/src/main/java/org/openmrs/module/stockmanagement/api/jobs/StockItemImportJob.java b/api/src/main/java/org/openmrs/module/stockmanagement/api/jobs/StockItemImportJob.java index f68bf3b..c6b87b4 100644 --- a/api/src/main/java/org/openmrs/module/stockmanagement/api/jobs/StockItemImportJob.java +++ b/api/src/main/java/org/openmrs/module/stockmanagement/api/jobs/StockItemImportJob.java @@ -9,6 +9,7 @@ import org.openmrs.module.stockmanagement.api.dto.*; import org.openmrs.module.stockmanagement.api.model.StockItem; import org.openmrs.module.stockmanagement.api.model.StockItemPackagingUOM; +import org.openmrs.module.stockmanagement.api.model.StockItemReference; import org.openmrs.module.stockmanagement.api.model.StockSource; import org.openmrs.module.stockmanagement.api.utils.GlobalProperties; @@ -62,6 +63,8 @@ public class StockItemImportJob { private int PURCHASE_PRICE_PUOM = 14; + private int VENDOR_REFERENCE_ITEM_CODE = 15; + private static Pattern NON_ASCII_PATTERN = Pattern.compile("[^A-Za-z0-9]"); public StockItemImportJob(Path file, boolean hasHeader) { @@ -86,7 +89,7 @@ private boolean isBlank(String value) { private Object validateLine(String[] line) { if (line == null || line.length == 0) return null; - Object[] objects = new Object[15]; + Object[] objects = new Object[16]; List errors = new ArrayList<>(); if (line.length < 3) { errors.add(Context.getMessageSourceService().getMessage("stockmanagement.importoperation.minimumfields")); @@ -216,6 +219,11 @@ private Object validateLine(String[] line) { objects[PREFERRED_VENDOR] = line[PREFERRED_VENDOR]; } + + if (line.length > VENDOR_REFERENCE_ITEM_CODE && !isBlank(line[VENDOR_REFERENCE_ITEM_CODE])) { + objects[VENDOR_REFERENCE_ITEM_CODE] = line[VENDOR_REFERENCE_ITEM_CODE]; + } + if (line.length > REORDER_LEVEL && !isBlank(line[REORDER_LEVEL])) { try { BigDecimal value = new BigDecimal(line[REORDER_LEVEL]); @@ -760,6 +768,17 @@ private void updateStockItems(Map stockItems) { saveStockItem=true; } + if (updates[VENDOR_REFERENCE_ITEM_CODE] != null && stockItem.getPreferredVendor() != null) { + StockItemReference stockItemReference = new StockItemReference(); + Set stockItemReferenceSet = new HashSet<>(); + stockItemReference.setStockReferenceCode(updates[VENDOR_REFERENCE_ITEM_CODE].toString()); + stockItemReference.setStockItem(stockItem); + stockItemReference.setReferenceSource(stockItem.getPreferredVendor()); + stockItemReferenceSet.add(stockItemReference); + stockItem.setStockItemReferences(stockItemReferenceSet); + saveStockItem = true; + } + if (saveStockItem) { stockItem.setDateChanged(new Date()); stockItem.setChangedBy(Context.getAuthenticatedUser()); diff --git a/api/src/main/java/org/openmrs/module/stockmanagement/api/model/StockItem.java b/api/src/main/java/org/openmrs/module/stockmanagement/api/model/StockItem.java index 84ea7b0..7ea9f2d 100644 --- a/api/src/main/java/org/openmrs/module/stockmanagement/api/model/StockItem.java +++ b/api/src/main/java/org/openmrs/module/stockmanagement/api/model/StockItem.java @@ -66,6 +66,9 @@ public class StockItem extends org.openmrs.BaseChangeableOpenmrsData implements @OneToMany(mappedBy = "stockItem") private Set stockItemPackagingUOMs; + @OneToMany(mappedBy = "stockItem", cascade = CascadeType.ALL, orphanRemoval = true) + private Set stockItemReferences; + @Field @Column(name = "is_drug", nullable = false) private Boolean isDrug; @@ -182,6 +185,27 @@ public StockItemPackagingUOM removeStockItemPackagingUom(StockItemPackagingUOM s return stockItemPackagingUom; } + public Set getStockItemReferences() { + return stockItemReferences; + } + + public void setStockItemReferences(Set stockItemReferences) { + this.stockItemReferences = stockItemReferences; + } + + public StockItemReference addStockItemReference(StockItemReference stockItemReference) { + getStockItemReferences().add(stockItemReference); + stockItemReference.setStockItem(this); + + return stockItemReference; + } + + public StockItemReference removeStockItemReferences(StockItemReference stockItemReference) { + getStockItemReferences().remove(stockItemReference); + stockItemReference.setStockItem(null); + return stockItemReference; + } + public boolean isHasExpiration() { return hasExpiration; } diff --git a/api/src/main/java/org/openmrs/module/stockmanagement/api/model/StockItemReference.java b/api/src/main/java/org/openmrs/module/stockmanagement/api/model/StockItemReference.java new file mode 100644 index 0000000..8c31597 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/stockmanagement/api/model/StockItemReference.java @@ -0,0 +1,74 @@ +package org.openmrs.module.stockmanagement.api.model; + +import org.hibernate.search.annotations.DocumentId; +import org.hibernate.search.annotations.Field; +import org.hibernate.search.annotations.Indexed; +import org.openmrs.Concept; +import org.openmrs.Drug; + +import javax.persistence.*; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Set; + +/** + * The persistent class for the stockmgmt_stock_item database table. + */ +@Entity(name = "stockmanagement.StockItemReference") +@Table(name = "stockmgmt_stock_item_reference") +@Indexed +public class StockItemReference extends org.openmrs.BaseChangeableOpenmrsData implements Serializable { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "stock_item_reference_id") + @DocumentId + private Integer id; + + @JoinColumn(name = "stock_source_id") + @ManyToOne(fetch = FetchType.LAZY) + private StockSource referenceSource; + + @JoinColumn(name = "stock_item_id") + @ManyToOne(fetch = FetchType.EAGER) + private StockItem stockItem; + + @Field + @Column(name = "stock_reference_code", length = 255) + private String stockReferenceCode; + + @Override + public Integer getId() { + return id; + } + + @Override + public void setId(Integer id) { + this.id = id; + } + + public StockSource getReferenceSource() { + return referenceSource; + } + + public void setReferenceSource(StockSource referenceSource) { + this.referenceSource = referenceSource; + } + + public StockItem getStockItem() { + return stockItem; + } + + public void setStockItem(StockItem stockItem) { + this.stockItem = stockItem; + } + + public String getStockReferenceCode() { + return stockReferenceCode; + } + + public void setStockReferenceCode(String stockReferenceCode) { + this.stockReferenceCode = stockReferenceCode; + } + +} diff --git a/api/src/main/resources/liquibase.xml b/api/src/main/resources/liquibase.xml index f684cd5..348a333 100644 --- a/api/src/main/resources/liquibase.xml +++ b/api/src/main/resources/liquibase.xml @@ -4564,4 +4564,82 @@ CREATE TRIGGER stockmgmt_location_after_delete operation_type in ('receipt', 'initial') + + + + + + + + Creating the stockmgmt_batch_job_owner table + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/api/src/test/java/org/openmrs/module/stockmanagement/EntityUtil.java b/api/src/test/java/org/openmrs/module/stockmanagement/EntityUtil.java index 35d1f80..d2ffc7f 100644 --- a/api/src/test/java/org/openmrs/module/stockmanagement/EntityUtil.java +++ b/api/src/test/java/org/openmrs/module/stockmanagement/EntityUtil.java @@ -20,7 +20,7 @@ public class EntityUtil { public static final String STOCK_OPERATION_TYPE_DATA_SET = BASE_DATASET_DIR + "StockOperationType.xml"; - public static final String STOCK_ITEMS_IMPORT_CSV = BASE_DATASET_DIR + "StockItemsImport.csv"; + public static final String STOCK_ITEMS_IMPORT_CSV = BASE_DATASET_DIR + "StockItemsImport2.csv"; private static Random random = new Random(); diff --git a/api/src/test/java/org/openmrs/module/stockmanagement/StockManagementServiceTest.java b/api/src/test/java/org/openmrs/module/stockmanagement/StockManagementServiceTest.java index dfcfb74..613d56a 100644 --- a/api/src/test/java/org/openmrs/module/stockmanagement/StockManagementServiceTest.java +++ b/api/src/test/java/org/openmrs/module/stockmanagement/StockManagementServiceTest.java @@ -735,9 +735,9 @@ public void getStockItemByDrug() { dao().saveStockItem(stockItem); stockManagementService.setDao(dao()); - StockItem stockItemLeft = stockManagementService.getStockItemByDrug(stockItem.getDrug().getId()); + List stockItemLeft = stockManagementService.getStockItemByDrug(stockItem.getDrug().getId()); assertNotNull(stockItemLeft); - assertEquals(stockItem.getUuid(), stockItemLeft.getUuid()); + assertTrue(stockItemLeft.stream().map(StockItem::getUuid).collect(Collectors.toList()).contains(stockItem.getUuid())); } @Test @@ -747,9 +747,9 @@ public void getStockItemByConcept() { dao().saveStockItem(stockItem); stockManagementService.setDao(dao()); - StockItem stockItemLeft = stockManagementService.getStockItemByConcept(stockItem.getConcept().getId()); + List stockItemLeft = stockManagementService.getStockItemByConcept(stockItem.getConcept().getId()); assertNotNull(stockItemLeft); - assertEquals(stockItem.getUuid(), stockItemLeft.getUuid()); + assertTrue(stockItemLeft.stream().map(StockItem::getUuid).collect(Collectors.toList()).contains(stockItem.getUuid())); } @Test diff --git a/api/src/test/resources/org/openmrs/module/stockmanagement/api/StockItemsImport.csv b/api/src/test/resources/org/openmrs/module/stockmanagement/api/StockItemsImport.csv index da97773..b113704 100644 --- a/api/src/test/resources/org/openmrs/module/stockmanagement/api/StockItemsImport.csv +++ b/api/src/test/resources/org/openmrs/module/stockmanagement/api/StockItemsImport.csv @@ -1,10 +1,10 @@ -2,456,yes,7,6,20,20,1,TEST 2,,National Medical Stores,50,20,13,20 -3,,no,7,6,20,20,10,TEST 3,T3,nationalMedical Stores,200,20,450,20 -11,,1,7,6,22,22,2,TEST 11,T11,National-Medical-Stores,100,22,1000,22, -12,6,0,7,6,23,23,30,TEST 12,,,500,23,500,23 -,5497,yes,7,6,20,20,1,TEST 2,,Uganda Medical Stores,50,20,13,20 -12,6,0,7,6,24,24,30,TEST 121,,,500,24,500,24 -2,456,yes,7,6,20,20,1,TEST 2,,National Medical Stores,50,20,13,20 -3,,no,7,6,20,20,10,TEST 3,T3,nationalMedical Stores,200,20,450,20 -11,,1,7,6,22,22,2,TEST 11,T11,National-Medical-Stores,100,22,1000,22, -,5497,0,7,6,20,20,1,TEST 2,,UgandaMedical Stores,50,20,13,20 \ No newline at end of file +2,456,yes,7,6,20,20,1,TEST 2,,National Medical Stores,50,20,13,20,NMS-001 +3,,no,7,6,20,20,10,TEST 3,T3,nationalMedical Stores,200,20,450,20,NMS-002 +11,,1,7,6,22,22,2,TEST 11,T11,National-Medical-Stores,100,22,1000,22,NMS-004 +12,6,0,7,6,23,23,30,TEST 12,,,500,23,500,23, +,5497,yes,7,6,20,20,1,TEST 2,,Uganda Medical Stores,50,20,13,20,NMS-005 +12,6,0,7,6,24,24,30,TEST 121,,,500,24,500,24, +2,456,yes,7,6,20,20,1,TEST 2,,National Medical Stores,50,20,13,20,NMS-006 +3,,no,7,6,20,20,10,TEST 3,T3,nationalMedical Stores,200,20,450,20,NMS-007 +11,,1,7,6,22,22,2,TEST 11,T11,National-Medical-Stores,100,22,1000,22,NMS-008 +,5497,0,7,6,20,20,1,TEST 2,,UgandaMedical Stores,50,20,13,20,NMS-009 \ No newline at end of file diff --git a/api/src/test/resources/org/openmrs/module/stockmanagement/api/StockItemsImport2.csv b/api/src/test/resources/org/openmrs/module/stockmanagement/api/StockItemsImport2.csv new file mode 100644 index 0000000..b113704 --- /dev/null +++ b/api/src/test/resources/org/openmrs/module/stockmanagement/api/StockItemsImport2.csv @@ -0,0 +1,10 @@ +2,456,yes,7,6,20,20,1,TEST 2,,National Medical Stores,50,20,13,20,NMS-001 +3,,no,7,6,20,20,10,TEST 3,T3,nationalMedical Stores,200,20,450,20,NMS-002 +11,,1,7,6,22,22,2,TEST 11,T11,National-Medical-Stores,100,22,1000,22,NMS-004 +12,6,0,7,6,23,23,30,TEST 12,,,500,23,500,23, +,5497,yes,7,6,20,20,1,TEST 2,,Uganda Medical Stores,50,20,13,20,NMS-005 +12,6,0,7,6,24,24,30,TEST 121,,,500,24,500,24, +2,456,yes,7,6,20,20,1,TEST 2,,National Medical Stores,50,20,13,20,NMS-006 +3,,no,7,6,20,20,10,TEST 3,T3,nationalMedical Stores,200,20,450,20,NMS-007 +11,,1,7,6,22,22,2,TEST 11,T11,National-Medical-Stores,100,22,1000,22,NMS-008 +,5497,0,7,6,20,20,1,TEST 2,,UgandaMedical Stores,50,20,13,20,NMS-009 \ No newline at end of file diff --git a/omod/src/main/java/org/openmrs/module/stockmanagement/web/controller/StockItemImportController.java b/omod/src/main/java/org/openmrs/module/stockmanagement/web/controller/StockItemImportController.java index bda02e6..5aef814 100644 --- a/omod/src/main/java/org/openmrs/module/stockmanagement/web/controller/StockItemImportController.java +++ b/omod/src/main/java/org/openmrs/module/stockmanagement/web/controller/StockItemImportController.java @@ -82,15 +82,9 @@ public ImportResult upload(@RequestParam(value = "file") MultipartFile file, Htt File workingDir = FileUtil.getWorkingDirectory(); String fileName = Context.getAuthenticatedUser().getUserId().toString() + "_" + UUID.randomUUID().toString(); File filePath = new File(workingDir, fileName); - try - - { + try { file.transferTo(filePath); - } catch ( - Exception exception - ) - - { + } catch (Exception exception) { ImportResult importResult = new ImportResult(); importResult.setSuccess(false); importResult.setErrors(new ArrayList<>());