use of Service

I am excited by the agility of CUBA Framework. Development is so fast that is something like dreaming to me.

I am now trying to learn how to use middle tier e.g. Service. I have following two files created and current problem is, i can’t compile it as having bugs in it and would appreciate for any help:

Business logic:
Sales order has tow entities: SalesOrder, SalesOrderLine. SalesOrderLine has Article of which BOM is created. BOM has following two entities:
BillOfMaterial, BillOfMaterialLine: BillOfMaterial entity has Article that links with SalesOrderLine whereas BillOfMaterialLine has Components and their quantity used. I am going to calculate materials requirements by multiplying order quantities from SalesOrderLine and BillOfMaterialLine

Error:


app-core:compileJava/Users/Mortoza/studio-projects/inteaccgms/modules/core/src/com/inteacc/gms/service/MrpServiceBean.java:47: error: incompatible types: Object cannot be converted to BillOfMaterial
                for (BillOfMaterial billOfMaterial : linesQuery.getResultList()) {
                                                                             ^
1 error
 FAILED
FAILURE: Build failed with an exception.

ServiceName: inteaccgms_MrpService

Interface: com.inteacc.gms.service.MrpService


package com.inteacc.gms.service;

/**
 * @author Mortoza
 */
public interface MrpService {
    String NAME = "inteaccgms_MrpService";

    void runMRP();

}

Bean: com.inteacc.gms.service.MrpServiceBean


/*
 * Copyright (c) 2016 inteaccgms
 */
package com.inteacc.gms.service;


import com.inteacc.gms.entity.*;
import com.haulmont.cuba.core.EntityManager;
import com.haulmont.cuba.core.Persistence;
import com.haulmont.cuba.core.Query;
import com.haulmont.cuba.core.TypedQuery;
import org.apache.commons.lang.time.DateUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.inject.Inject;
import java.math.BigDecimal;
import java.util.*;

/**
 * @author Mortoza
 */
@Service(MrpService.NAME)
public class MrpServiceBean implements MrpService {

    @Inject
    private Persistence persistence;

    @Override
    @Transactional
    public void runMRP() {
        
        EntityManager em = persistence.getEntityManager();

        String queryString = "select s from inteaccgms$SalesOrder s";

        List<SalesOrder> orderList = em.createQuery(queryString, SalesOrder.class).getResultList();

//        em.getTransaction().begin();

        for (SalesOrder order : orderList) {

            // process Sales order detail
            for (SalesOrderLine s: order.getLines()) {
                //Get BOM of the article
                com.haulmont.cuba.core.Query linesQuery = em.createQuery("select l from inteaccgms$SalesOrderLine l " +
                        "inner join inteaccgms$BillOfMaterial b on ");
                for (BillOfMaterial billOfMaterial : linesQuery.getResultList()) {
                    System.out.println(billOfMaterial);
                    //Calculate Material requirements

                    //save calculation

                }
            }
        }

//        em.flush();
//        em.clear();
//        em.getTransaction().commit();

    }

}

Thank you for the positive feedback!

The cause of the compilation error is here:

Query linesQuery = em.createQuery("select l from inteaccgms$SalesOrderLine ...");

You create a non-typed Query, and when you get results from it, they are of type Object. Just add the result class to the createQuery() method and the results will be of the required type (see https://doc.cuba-platform.com/manual-6.0/query.html):

TypedQuery<BillOfMaterial> linesQuery = em.createQuery("select b from inteaccgms$BillOfMaterial b where ...", BillOfMaterial.class); 
for (BillOfMaterial billOfMaterial : linesQuery.getResultList()) { 
    System.out.println(billOfMaterial); 
}

I don’t understand how BillOfMaterial is linked to SalesOrderLine, so I’m not sure what should be in the “where” clause of the query.
And what do you mean by Article? An attribute?

Hi
Thanks. I shall correct it and give a try.
Let me answer your question, thanks for asking. I have prepared a diagram explaining the link and used an example to explain what I am trying to achieve by using the Service. The file is attached.

Example of BOM.xlsx (14.1K)

Good diagram, now I see the relations between your entities.
To be honest, I will not be able to help you with high level tasks like “calculate materials requirements”. Please ask more concrete questions, like “my query doesn’t work, how to fix it”.

Hi, Yes I am back with questions. Thanks for your help.
I am getting some difficulty in using numbers and calculation while compiling the application. Here is the log:

 
CUBA Studiointeaccgms 
? 
BuildRunHelp 
??????? 
PROJECT PROPERTIES 
ENTITIES 
ENTITY LISTENERS 
ENUMERATIONS 
SCREENS 
SERVICES 
?New?Edit?Remove?IDE 
com.inteacc.gms.service 
inteaccgms_MrpService 
MAIN MENU 
HSQLDBon port 9001, 
IDEon port 48561 
Web application 
localhost:8080/app 
SERVICE DESIGNER?OK?Apply?Show changes?Close 
PROPERTIES 
INTERFACE 
BEAN 
 
1 
2 
3 
4 
5 
6 
7 
8 
/* 
 * Copyright (c) 2016 inteaccgms 
 */ 
package com.inteacc.gms.service; 
import com.haulmont.cuba.core.app.NumberIdService; 
import com.haulmont.cuba.core.app.cache.ObjectsCache; 
[21:10:47.896] Building the project 
:app-core:assembleDbScripts UP-TO-DATE 
:app-core:dbScriptsArchive UP-TO-DATE 
:app-global:compileJava UP-TO-DATE 
:app-global:enhance UP-TO-DATE 
:app-global:processResources UP-TO-DATE 
:app-global:classes UP-TO-DATE 
:app-global:jar UP-TO-DATE 
:app-core:compileJava/Users/Mortoza/studio-projects/inteaccgms/modules/core/src/com/inteacc/gms/service/MrpServiceBean.java:67: error: cannot find symbol 
        BiGDecimal wastageRate = BigDecimal.ZERO; 
        ^ 
  symbol:   class BiGDecimal 
  location: class MrpServiceBean 
/Users/Mortoza/studio-projects/inteaccgms/modules/core/src/com/inteacc/gms/service/MrpServiceBean.java:101: error: no suitable constructor found for BigDecimal(BigDecimal) 
                        grossRequirements = new BigDecimal(orderQuantity).divide(1 - new BigDecimal(baseQuantity).divide(100)); 
                                                                                     ^ 
    constructor BigDecimal.BigDecimal(char[]) is not applicable 
      (argument mismatch; BigDecimal cannot be converted to char[]) 
    constructor BigDecimal.BigDecimal(String) is not applicable 
      (argument mismatch; BigDecimal cannot be converted to String) 
    constructor BigDecimal.BigDecimal(double) is not applicable 
      (argument mismatch; BigDecimal cannot be converted to double) 
    constructor BigDecimal.BigDecimal(BigInteger) is not applicable 
      (argument mismatch; BigDecimal cannot be converted to BigInteger) 
    constructor BigDecimal.BigDecimal(int) is not applicable 
      (argument mismatch; BigDecimal cannot be converted to int) 
    constructor BigDecimal.BigDecimal(long) is not applicable 
      (argument mismatch; BigDecimal cannot be converted to long) 
/Users/Mortoza/studio-projects/inteaccgms/modules/core/src/com/inteacc/gms/service/MrpServiceBean.java:101: error: no suitable constructor found for BigDecimal(BigDecimal) 
                        grossRequirements = new BigDecimal(orderQuantity).divide(1 - new BigDecimal(baseQuantity).divide(100)); 
                                            ^ 
    constructor BigDecimal.BigDecimal(char[]) is not applicable 
      (argument mismatch; BigDecimal cannot be converted to char[]) 
    constructor BigDecimal.BigDecimal(String) is not applicable 
      (argument mismatch; BigDecimal cannot be converted to String) 
    constructor BigDecimal.BigDecimal(double) is not applicable 
      (argument mismatch; BigDecimal cannot be converted to double) 
    constructor BigDecimal.BigDecimal(BigInteger) is not applicable 
      (argument mismatch; BigDecimal cannot be converted to BigInteger) 
    constructor BigDecimal.BigDecimal(int) is not applicable 
      (argument mismatch; BigDecimal cannot be converted to int) 
    constructor BigDecimal.BigDecimal(long) is not applicable 
      (argument mismatch; BigDecimal cannot be converted to long) 
/Users/Mortoza/studio-projects/inteaccgms/modules/core/src/com/inteacc/gms/service/MrpServiceBean.java:108: error: no suitable constructor found for BigDecimal(BigDecimal) 
                            componentRequirements =new BigDecimal(grossRequirements).divide(baseQuantity).multiply(new BigDecimal(bomLines.getQuantity())); 
                                                                                                                   ^ 
    constructor BigDecimal.BigDecimal(char[]) is not applicable 
      (argument mismatch; BigDecimal cannot be converted to char[]) 
    constructor BigDecimal.BigDecimal(String) is not applicable 
      (argument mismatch; BigDecimal cannot be converted to String) 
    constructor BigDecimal.BigDecimal(double) is not applicable 
      (argument mismatch; BigDecimal cannot be converted to double) 
    constructor BigDecimal.BigDecimal(BigInteger) is not applicable 
      (argument mismatch; BigDecimal cannot be converted to BigInteger) 
    constructor BigDecimal.BigDecimal(int) is not applicable 
      (argument mismatch; BigDecimal cannot be converted to int) 
    constructor BigDecimal.BigDecimal(long) is not applicable 
      (argument mismatch; BigDecimal cannot be converted to long) 
/Users/Mortoza/studio-projects/inteaccgms/modules/core/src/com/inteacc/gms/service/MrpServiceBean.java:108: error: no suitable constructor found for BigDecimal(BigDecimal) 
                            componentRequirements =new BigDecimal(grossRequirements).divide(baseQuantity).multiply(new BigDecimal(bomLines.getQuantity())); 
                                                   ^ 
    constructor BigDecimal.BigDecimal(char[]) is not applicable 
      (argument mismatch; BigDecimal cannot be converted to char[]) 
    constructor BigDecimal.BigDecimal(String) is not applicable 
      (argument mismatch; BigDecimal cannot be converted to String) 
    constructor BigDecimal.BigDecimal(double) is not applicable 
      (argument mismatch; BigDecimal cannot be converted to double) 
    constructor BigDecimal.BigDecimal(BigInteger) is not applicable 
      (argument mismatch; BigDecimal cannot be converted to BigInteger) 
    constructor BigDecimal.BigDecimal(int) is not applicable 
      (argument mismatch; BigDecimal cannot be converted to int) 
    constructor BigDecimal.BigDecimal(long) is not applicable 
      (argument mismatch; BigDecimal cannot be converted to long) 
/Users/Mortoza/studio-projects/inteaccgms/modules/core/src/com/inteacc/gms/service/MrpServiceBean.java:109: error: no suitable constructor found for BigDecimal(BigDecimal) 
                            componentGrossRequirements = new BigDecimal(componentRequirements).divide(1-new BigDecimal(bomLines.getWastagePercentage())/100); 
                                                                                                        ^ 
    constructor BigDecimal.BigDecimal(char[]) is not applicable 
      (argument mismatch; BigDecimal cannot be converted to char[]) 
    constructor BigDecimal.BigDecimal(String) is not applicable 
      (argument mismatch; BigDecimal cannot be converted to String) 
    constructor BigDecimal.BigDecimal(double) is not applicable 
      (argument mismatch; BigDecimal cannot be converted to double) 
    constructor BigDecimal.BigDecimal(BigInteger) is not applicable 
      (argument mismatch; BigDecimal cannot be converted to BigInteger) 
    constructor BigDecimal.BigDecimal(int) is not applicable 
      (argument mismatch; BigDecimal cannot be converted to int) 
    constructor BigDecimal.BigDecimal(long) is not applicable 
      (argument mismatch; BigDecimal cannot be converted to long) 
/Users/Mortoza/studio-projects/inteaccgms/modules/core/src/com/inteacc/gms/service/MrpServiceBean.java:109: error: no suitable constructor found for BigDecimal(BigDecimal) 
                            componentGrossRequirements = new BigDecimal(componentRequirements).divide(1-new BigDecimal(bomLines.getWastagePercentage())/100); 
                                                         ^ 
    constructor BigDecimal.BigDecimal(char[]) is not applicable 
      (argument mismatch; BigDecimal cannot be converted to char[]) 
    constructor BigDecimal.BigDecimal(String) is not applicable 
      (argument mismatch; BigDecimal cannot be converted to String) 
    constructor BigDecimal.BigDecimal(double) is not applicable 
      (argument mismatch; BigDecimal cannot be converted to double) 
    constructor BigDecimal.BigDecimal(BigInteger) is not applicable 
      (argument mismatch; BigDecimal cannot be converted to BigInteger) 
    constructor BigDecimal.BigDecimal(int) is not applicable 
      (argument mismatch; BigDecimal cannot be converted to int) 
    constructor BigDecimal.BigDecimal(long) is not applicable 
      (argument mismatch; BigDecimal cannot be converted to long) 
Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output 
7 errors 
 FAILED 
FAILURE: Build failed with an exception. 
* What went wrong: 
Execution failed for task ':app-core:compileJava'. 
> Compilation failed; see the compiler error output for details. 
* Try: 
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. 
BUILD FAILED 
Total time: 0.902 secs 
[21:10:49.193] Task 'assemble' failed 
org.gradle.api.internal.tasks.compile.CompilationFailedException: Compilation failed; see the compiler error output for details. 



and here is the service file

 
/* 
 * Copyright (c) 2016 inteaccgms 
 */ 
package com.inteacc.gms.service; 
import com.haulmont.cuba.core.app.NumberIdService; 
import com.haulmont.cuba.core.app.cache.ObjectsCache; 
import com.inteacc.gms.entity.*; 
import com.haulmont.cuba.core.EntityManager; 
import com.haulmont.cuba.core.Persistence; 
import com.haulmont.cuba.core.Query; 
import com.haulmont.cuba.core.TypedQuery; 
import groovy.json.internal.NumberValue; 
import org.apache.commons.lang.time.DateUtils; 
import org.codehaus.groovy.runtime.typehandling.BigDecimalMath; 
import org.eclipse.persistence.jpa.jpql.parser.DateTime; 
import org.hsqldb.lib.Iterator; 
import org.springframework.stereotype.Service; 
import org.springframework.transaction.annotation.Transactional; 
import org.springframework.util.NumberUtils; 
import javax.inject.Inject; 
import java.math.BigDecimal; 
import java.util.*; 
/** 
 * @author Mortoza 
 */ 
@Service(MrpService.NAME) 
public class MrpServiceBean implements MrpService { 
    @Inject 
    private Persistence persistence; 
    @Override 
    @Transactional 
    public void runMRP() { 
        EntityManager em = persistence.getEntityManager(); 
          String queryString = "select s from inteaccgms$SalesOrder s"; 
        TypedQuery <SalesOrder> orderList = em.createQuery(queryString, SalesOrder.class); 
//        em.getTransaction().begin(); 
        BigDecimal orderQuantity=BigDecimal.ZERO; 
        BigDecimal baseQuantity =BigDecimal.ZERO; 
        BigDecimal grossRequirements = BigDecimal.ZERO; 
        BigDecimal componentQty = BigDecimal.ZERO; 
        BiGDecimal wastageRate = BigDecimal.ZERO; 
        BigDecimal componentRequirements = BigDecimal.ZERO; 
        BigDecimal componentGrossRequirements = BigDecimal.ZERO; 
        for (SalesOrder order : orderList.getResultList()) { 
            TypedQuery<SalesOrderLine> solQuery = em.createQuery("select l from inteaccgms$SalesOrderLine l where l.id = ?1", SalesOrderLine.class); 
            solQuery.setParameter(1, order.getId()); 
            for (SalesOrderLine soline : solQuery.getResultList()) { 
                orderQuantity =(BigDecimal)soline.getQuantity(); 
                TypedQuery<Article> aQuery = em.createQuery("select a from inteaccgms$Article a where a.ID = :?1", Article.class); 
                solQuery.setParameter(1, soline.getId()); 
                // process Sales order detail 
                for (Article a : aQuery.getResultList()) { 
                    //Get BOM of the article 
                    TypedQuery<BillOfMaterial> bomQuery = em.createQuery("select b from inteaccgms$BillOfMaterial b where b.Article.id = : ?1", BillOfMaterial.class); 
                    bomQuery.setParameter(1, a.getId()); 
                    for (BillOfMaterial bom : bomQuery.getResultList()) { 
                        TypedQuery<BillOfMaterialLines> bomlineQuery = em.createQuery("select b from inteaccgms$BillOfMaterialLine b where b.id = : ?1", BillOfMaterialLines.class); 
                        bomlineQuery.setParameter(1, bom.getId()); 
                        baseQuantity =(BigDecimal)bom.getBaseQuantity(); 
                        grossRequirements = new BigDecimal(orderQuantity).divide(1 - new BigDecimal(baseQuantity).divide(100)); 
                        for (BillOfMaterialLines bomLines : bomlineQuery.getResultList()) { 
                            componentRequirements =new BigDecimal(grossRequirements).divide(baseQuantity).multiply(new BigDecimal(bomLines.getQuantity())); 
                            componentGrossRequirements = new BigDecimal(componentRequirements).divide(1-new BigDecimal(bomLines.getWastagePercentage())/100); 
                        //save calculation 
                            Mrp mrp = new Mrp(); 
                            mrp.setSalesOrder(order); 
                            mrp.setQuantity(componentGrossRequirements); 
                            mrp.setMaterial(bomLines.getMaterial()); 
                            mrp.setArticle(bom.getArticle()); 
                            em.persist(mrp); 
                        } 
                    } 
                } 
            } 
        } 
    } 
} 



Well, the log messages clearly explain your errors:
cannot find symbol BiGDecimal - typo
no suitable constructor found for BigDecimal(BigDecimal) - learn how to work with BigDecimal
These errors have nothing to do with CUBA.

Hi
I have fixed the BigDecimal issue and the program is compiling well without any error. However, There is no result populated in the entity after calculation. Is there any good way to trace where is the gap? I append below all codes if you can help…
MRP screen where the data is displayed after calculation and a button (Run MRP) is linked to the service. I might be making mistake here but not sure,

 
<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<window xmlns="[url=http://schemas.haulmont.com/cuba/window.xsd]http://schemas.haulmont.com/cuba/window.xsd"[/url]; 
        caption="msg://browseCaption" 
        class="com.inteacc.gms.gui.mrp.MrpBrowse" 
        focusComponent="mrpsTable" 
        lookupComponent="mrpsTable" 
        messagesPack="com.inteacc.gms.gui.mrp"> 
    <dsContext> 
        <collectionDatasource id="mrpsDs" 
                              class="com.inteacc.gms.entity.Mrp" 
                              view="mrp-view"> 
            <query> 
                <![CDATA[select e from inteaccgms$Mrp e]]> 
            </query> 
        </collectionDatasource> 
    </dsContext> 
    <layout expand="mrpsTable" 
            spacing="true"> 
        <filter id="filter" 
                applyTo="mrpsTable" 
                datasource="mrpsDs"> 
            <properties include=".*"></properties> 
        </filter> 
        <table id="mrpsTable" 
               width="100%"> 
            <actions> 
                <action id="refresh"></action> 
                <action id="excel"></action> 
            </actions> 
            <columns> 
                <column id="salesOrder"/> 
                <column id="article"/> 
                <column id="material"/> 
                <column id="mrpDate"/> 
                <column id="quantity"/> 
                <column id="requiredDate"/> 
                <column id="componentAvailabilityDate"/> 
            </columns> 
            <rows datasource="mrpsDs"></rows> 
            <rowsCount></rowsCount> 
            <buttonsPanel id="buttonsPanel" 
                          alwaysVisible="true"> 
                <button id="calculateBtn" 
                        caption="Run MRP" 
                        invoke="onCalculateBtnClick"></button> 
                <button id="refreshBtn" 
                        action="mrpsTable.refresh"></button> 
                <button id="excelBtn" 
                        action="mrpsTable.excel"></button> 
            </buttonsPanel> 
        </table> 
    </layout> 
</window> 

Controller

 
/* 
 * Copyright (c) 2016 inteaccgms 
 */ 
package com.inteacc.gms.gui.mrp; 
import com.haulmont.cuba.gui.components.AbstractLookup; 
import com.haulmont.cuba.gui.components.Component; 
import com.inteacc.gms.service.MrpService; 
import javax.inject.Inject; 
/** 
 * @author Mortoza 
 */ 
public class MrpBrowse extends AbstractLookup { 
@Inject 
MrpService service; 
    public void onCalculateBtnClick(Component source) { 
        service.runMRP(); 
    } 
} 



Interface

 
/* 
 * Copyright (c) 2016 inteaccgms 
 */ 
package com.inteacc.gms.service; 
/** 
 * @author Mortoza 
 */ 
public interface MrpService { 
    String NAME = "inteaccgms_MrpService"; 
    void runMRP(); 
} 



Bean

 
/* 
 * Copyright (c) 2016 inteaccgms 
 */ 
package com.inteacc.gms.service; 
import com.haulmont.cuba.core.app.NumberIdService; 
import com.haulmont.cuba.core.app.cache.ObjectsCache; 
import com.inteacc.gms.entity.*; 
import com.haulmont.cuba.core.EntityManager; 
import com.haulmont.cuba.core.Persistence; 
import com.haulmont.cuba.core.Query; 
import com.haulmont.cuba.core.TypedQuery; 
import groovy.json.internal.NumberValue; 
import org.apache.commons.lang.time.DateUtils; 
import org.codehaus.groovy.runtime.typehandling.BigDecimalMath; 
import org.eclipse.persistence.jpa.jpql.parser.DateTime; 
import org.hsqldb.lib.Iterator; 
import org.springframework.stereotype.Service; 
import org.springframework.transaction.annotation.Transactional; 
import org.springframework.util.NumberUtils; 
import com.haulmont.cuba.core.Transaction; 
import com.haulmont.cuba.core.global.Metadata; 
import javax.inject.Inject; 
import java.math.BigDecimal; 
import java.util.*; 
/** 
 * @author Mortoza 
 */ 
@Service(MrpService.NAME) 
public class MrpServiceBean implements MrpService { 
    @Inject 
    private Persistence persistence; 
    @Inject 
    protected Metadata metadata; 
    @Override 
    @Transactional 
    public void runMRP() { 
        EntityManager em = persistence.getEntityManager(); 
          String queryString = "select s from inteaccgms$SalesOrder s"; 
        TypedQuery <SalesOrder> orderList = em.createQuery(queryString, SalesOrder.class); 
        BigDecimal orderQuantity=BigDecimal.ZERO; 
        BigDecimal baseQuantity =BigDecimal.ZERO; 
        BigDecimal rejectRate =BigDecimal.ZERO; 
        BigDecimal grossRequirements = BigDecimal.ZERO; 
        BigDecimal componentQty = BigDecimal.ZERO; 
        BigDecimal wastageRate = BigDecimal.ZERO; 
        BigDecimal componentRequirements = BigDecimal.ZERO; 
        BigDecimal componentGrossRequirements = BigDecimal.ZERO; 
        for (SalesOrder order : orderList.getResultList()) { 
            TypedQuery<SalesOrderLine> solQuery = em.createQuery("select l from inteaccgms$SalesOrderLine l where l.id = ?1", SalesOrderLine.class); 
            solQuery.setParameter(1, order.getId()); 
            for (SalesOrderLine soline : solQuery.getResultList()) { 
                orderQuantity =new BigDecimal(soline.getQuantity().longValue()); 
                TypedQuery<Article> aQuery = em.createQuery("select a from inteaccgms$Article a where a.ID = :?1", Article.class); 
                solQuery.setParameter(1, soline.getId()); 
         
                for (Article a : aQuery.getResultList()) { 
                             TypedQuery<BillOfMaterial> bomQuery = em.createQuery("select b from inteaccgms$BillOfMaterial b where b.Article.id = : ?1", BillOfMaterial.class); 
                    bomQuery.setParameter(1, a.getId()); 
                    for (BillOfMaterial bom : bomQuery.getResultList()) { 
                        baseQuantity =new BigDecimal(bom.getBaseQuantity().longValue()); 
                        rejectRate =new BigDecimal(bom.getRejectPercentage().longValue()); 
                        rejectRate=rejectRate.divide(new BigDecimal(100)); 
                        TypedQuery<BillOfMaterialLines> bomlineQuery = em.createQuery("select b from inteaccgms$BillOfMaterialLine b where b.id = : ?1", BillOfMaterialLines.class); 
                        bomlineQuery.setParameter(1, bom.getId()); 
                    
                        grossRequirements = new BigDecimal(orderQuantity.longValue()).divide(BigDecimal.ONE.subtract(rejectRate)); 
                        for (BillOfMaterialLines bomLines : bomlineQuery.getResultList()) { 
                            componentQty=new BigDecimal(bomLines.getQuantity().longValue()); 
                            wastageRate = new BigDecimal(bomLines.getWastagePercentage().longValue()); 
                            wastageRate=wastageRate.divide(new BigDecimal(100)); 
                            componentRequirements =new BigDecimal(grossRequirements.longValue()).divide(baseQuantity).multiply(new BigDecimal(bomLines.getQuantity().longValue())); 
                            componentGrossRequirements = new BigDecimal(componentRequirements.longValue()).divide(BigDecimal.ONE.subtract(wastageRate)); 
                        //save calculation 
                            Mrp mrp = metadata.create(Mrp.class); 
                            mrp.setSalesOrder(order); 
                            mrp.setQuantity(componentGrossRequirements); 
                            mrp.setMaterial(bomLines.getMaterial()); 
                            mrp.setArticle(bom.getArticle()); 
                             try (Transaction tx = persistence.createTransaction()) { 
                                persistence.getEntityManager().persist(mrp); 
                                tx.commit(); 
                            } 
                        } 
                    } 
                } 
            } 
        } 
    } 
} 



First. about BigDecimal usage. I think you can simplify your code if instead of

grossRequirements = new BigDecimal(orderQuantity.longValue()).divide(BigDecimal.ONE.subtract(rejectRate));  

you will write

grossRequirements = orderQuantity.divide(BigDecimal.ONE.subtract(rejectRate)); 

You don’t have to create new instances manually, the BigDecimal class is immutable, and all its methods return new instances.

Second, you shouldn’t create a new transaction when persisting the Mrp entity at the end. The whole method is marked as @Transactional and that’s enough.

And the main point: probably your third query never executes, because it contains an error - uppercased ID, which shouldn’t work. If the execution flow come to this query, you would get an error. So I think the previous queries do not yield an expected result. You can either debug your code step-by-step (see https://doc.cuba-platform.com/manual-6.0/debug_setup.html), or add some logging inside your code (see https://doc.cuba-platform.com/manual-6.0/logging.html).

Hi
Thank you. I have corrected the code as suggested. As i don’t see result, i tried to use the 2nd option you have indicated to log and read that from Application log menu but do not see anything. i have set log at controller as well as at bean.


package com.inteacc.gms.gui.mrp;

import com.haulmont.cuba.gui.components.AbstractLookup;
import com.haulmont.cuba.gui.components.Component;
import com.inteacc.gms.service.MrpService;
import javax.inject.Inject;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author Mortoza
 */
public class MrpBrowse extends AbstractLookup {

 // create loggerca
    private Logger log = LoggerFactory.getLogger(MrpBrowse.class);


@Inject
MrpService service;



    public void onCalculateBtnClick(Component source) {
// output message with DEBUG level
        log.debug("before runMRP invoked");

        service.runMRP();
    }
}

and the bean


/*
 * Copyright (c) 2016 inteaccgms
 */
package com.inteacc.gms.service;


import com.haulmont.cuba.core.app.NumberIdService;
import com.haulmont.cuba.core.app.cache.ObjectsCache;
import com.inteacc.gms.entity.*;
import com.haulmont.cuba.core.EntityManager;
import com.haulmont.cuba.core.Persistence;
import com.haulmont.cuba.core.Query;
import com.haulmont.cuba.core.TypedQuery;
import groovy.json.internal.NumberValue;
import org.apache.commons.lang.time.DateUtils;
import org.codehaus.groovy.runtime.typehandling.BigDecimalMath;
import org.eclipse.persistence.jpa.jpql.parser.DateTime;
import org.hsqldb.lib.Iterator;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.NumberUtils;

import com.haulmont.cuba.core.Transaction;
import com.haulmont.cuba.core.global.Metadata;


import javax.inject.Inject;
import java.math.BigDecimal;
import java.util.*;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author Mortoza
 */
@Service(MrpService.NAME)
public class MrpServiceBean implements MrpService {

    // create logger
    private Logger log = LoggerFactory.getLogger(MrpServiceBean.class);


    @Inject
    private Persistence persistence;


    @Inject
    protected Metadata metadata;

    @Override
    @Transactional
    public void runMRP() {

        // output message with DEBUG level
        log.debug("runMRP invoked");


        EntityManager em = persistence.getEntityManager();

        /*
        String queryString = " select o.quantity, o.ID as order_id, o.SalesOrderDATE as order_date, " +
                "o.QUANTITY as quantity, b.BaseQuantity as base_quantity, " +
                "b.RejectPercentage as reject_percentage, line.material_ID as material_id, " +
                "line.componentRequired as components_required, line.wastagePercentage as wastage_percentage " +
            "from inteaccgms$SalesOrder o  " +
                "left join inteaccgms$SalesOrderLine line on line.SalesOrder_ID = o.id and line.DELETE_TS is null " +
                "left join inteaccgms$Article a on  a.id = line.SALESORDERLINE.Article_ID  and a.DELETE_TS is null " +
                "left join inteaccgms$BillOfMaterial b on b.ARTICLE_ID = a.id  " +
                "left join inteaccgms$BillOfMaterialLine bl on bl.BillOfMaterial_ID = b.id " +
                "left join inteaccgms$Material m on bl.Material_ID = m.id and m.DELETE_TS is null";

*/

        String queryString = "select s from inteaccgms$SalesOrder s";

        TypedQuery <SalesOrder> orderList = em.createQuery(queryString, SalesOrder.class);

//        em.getTransaction().begin();

        BigDecimal orderQuantity=BigDecimal.ZERO;
        BigDecimal baseQuantity =BigDecimal.ZERO;
        BigDecimal rejectRate =BigDecimal.ZERO;
        BigDecimal grossRequirements = BigDecimal.ZERO;
        BigDecimal componentQty = BigDecimal.ZERO;
        BigDecimal wastageRate = BigDecimal.ZERO;
        BigDecimal componentRequirements = BigDecimal.ZERO;
        BigDecimal componentGrossRequirements = BigDecimal.ZERO;

        for (SalesOrder order : orderList.getResultList()) {

            TypedQuery<SalesOrderLine> solQuery = em.createQuery("select l from inteaccgms$SalesOrderLine l where l.id = ?1", SalesOrderLine.class);
            solQuery.setParameter(1, order.getId());

            for (SalesOrderLine soline : solQuery.getResultList()) {
                orderQuantity =new BigDecimal(soline.getQuantity().longValue());

                TypedQuery<Article> aQuery = em.createQuery("select a from inteaccgms$Article a where a.id = :?1", Article.class);
                solQuery.setParameter(1, soline.getId());

                // process Sales order detail
                for (Article a : aQuery.getResultList()) {
                    //Get BOM of the article

                    TypedQuery<BillOfMaterial> bomQuery = em.createQuery("select b from inteaccgms$BillOfMaterial b where b.Article.id = : ?1", BillOfMaterial.class);
                    bomQuery.setParameter(1, a.getId());

                    for (BillOfMaterial bom : bomQuery.getResultList()) {

                        baseQuantity =new BigDecimal(bom.getBaseQuantity().longValue());
                        rejectRate =new BigDecimal(bom.getRejectPercentage().longValue());
                        rejectRate=rejectRate.divide(new BigDecimal(100));

                        TypedQuery<BillOfMaterialLines> bomlineQuery = em.createQuery("select b from inteaccgms$BillOfMaterialLine b where b.id = : ?1", BillOfMaterialLines.class);
                        bomlineQuery.setParameter(1, bom.getId());


                        //CALCULATION FORMULA
                        //====================================================
                        //Gross Requirements = Order Quantity / (1 - Rejects%)
                        //COMPONENT Gross requirements = (Gross Requirements / Base QUantity) x componentQuantity + Wastage Qty
                        //Wastage Qty of components = component Requirements / (1-wastage /100)

                        grossRequirements = orderQuantity.divide(BigDecimal.ONE.subtract(rejectRate));

                        for (BillOfMaterialLines bomLines : bomlineQuery.getResultList()) {

                        //Calculate Material requirements before wastage
                            wastageRate = new BigDecimal(bomLines.getWastagePercentage().longValue());
                            wastageRate=wastageRate.divide(new BigDecimal(100));

                            componentRequirements =grossRequirements.divide(baseQuantity).multiply(new BigDecimal(bomLines.getQuantity().longValue()));
                            componentGrossRequirements = componentRequirements.divide(BigDecimal.ONE.subtract(wastageRate));

                        //save calculation
                            Mrp mrp = metadata.create(Mrp.class);
                            mrp.setSalesOrder(order);
                            mrp.setQuantity(componentGrossRequirements);
                            mrp.setMaterial(bomLines.getMaterial());
                            mrp.setArticle(bom.getArticle());
                           // mrp.setMrpDate(DateTimeUtils.getDate());

                           // try (Transaction tx = persistence.createTransaction()) {
                                persistence.getEntityManager().persist(mrp);
                           //     tx.commit();
                           // }



                        }
                    }
                }

            }


        }

//        em.flush();
//        em.clear();
//        em.getTransaction().commit();


    }


}