IDEMPIERE-5391 Unit Test: Fix support for parallel execution of test (#1446)
This commit is contained in:
parent
a558644949
commit
ce22d1cc51
|
@ -24,7 +24,6 @@ import java.util.Arrays;
|
|||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
@ -151,10 +150,9 @@ public class MTable extends X_AD_Table implements ImmutablePOSupport
|
|||
{
|
||||
if (tableName == null)
|
||||
return null;
|
||||
Iterator<MTable> it = s_cache.values().iterator();
|
||||
while (it.hasNext())
|
||||
MTable[] tables = s_cache.values().toArray(new MTable[0]);
|
||||
for (MTable retValue : tables)
|
||||
{
|
||||
MTable retValue = it.next();
|
||||
if (tableName.equalsIgnoreCase(retValue.getTableName()))
|
||||
{
|
||||
return s_cache.get (ctx, retValue.get_ID(), e -> new MTable(ctx, e));
|
||||
|
|
|
@ -0,0 +1,405 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="org.eclipse.pde.ui.JunitLaunchConfig">
|
||||
<booleanAttribute key="append.args" value="true"/>
|
||||
<stringAttribute key="application" value="org.eclipse.pde.junit.runtime.coretestapplication"/>
|
||||
<booleanAttribute key="askclear" value="false"/>
|
||||
<booleanAttribute key="automaticAdd" value="false"/>
|
||||
<booleanAttribute key="automaticValidate" value="true"/>
|
||||
<stringAttribute key="bootstrap" value=""/>
|
||||
<stringAttribute key="checked" value="[NONE]"/>
|
||||
<booleanAttribute key="clearConfig" value="true"/>
|
||||
<booleanAttribute key="clearws" value="true"/>
|
||||
<booleanAttribute key="clearwslog" value="false"/>
|
||||
<stringAttribute key="configLocation" value="${workspace_loc}/.metadata/.plugins/org.eclipse.pde.core/pde-junit"/>
|
||||
<booleanAttribute key="default" value="false"/>
|
||||
<setAttribute key="deselected_workspace_bundles"/>
|
||||
<booleanAttribute key="includeOptional" value="false"/>
|
||||
<stringAttribute key="location" value="${workspace_loc}/../junit-workspace"/>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||
<listEntry value="/org.idempiere.test"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||
<listEntry value="4"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.eclemma.core.SCOPE_IDS">
|
||||
<listEntry value="=org.adempiere.install/src"/>
|
||||
<listEntry value="=org.adempiere.server/src\/main\/server"/>
|
||||
<listEntry value="=org.idempiere.printformat.editor/src"/>
|
||||
<listEntry value="=org.idempiere.keikai/src"/>
|
||||
<listEntry value="=org.adempiere.replication/src"/>
|
||||
<listEntry value="=org.adempiere.plugin.utils/src"/>
|
||||
<listEntry value="=org.compiere.db.oracle.provider/src"/>
|
||||
<listEntry value="=org.adempiere.ui/src"/>
|
||||
<listEntry value="=org.adempiere.pipo.handlers/src"/>
|
||||
<listEntry value="=org.compiere.db.postgresql.provider/src"/>
|
||||
<listEntry value="=org.adempiere.report.jasper/src"/>
|
||||
<listEntry value="=org.adempiere.ui.zk/WEB-INF\/src"/>
|
||||
<listEntry value="=org.apache.ecs/src"/>
|
||||
<listEntry value="=org.idempiere.felix.webconsole/src"/>
|
||||
<listEntry value="=org.idempiere.webservices/WEB-INF\/src"/>
|
||||
<listEntry value="=org.adempiere.pipo/src"/>
|
||||
<listEntry value="=org.adempiere.payment.processor/src"/>
|
||||
<listEntry value="=org.adempiere.webstore/src"/>
|
||||
<listEntry value="=org.adempiere.server/src\/main\/home"/>
|
||||
<listEntry value="=org.adempiere.base.callout/src"/>
|
||||
<listEntry value="=org.adempiere.base/src"/>
|
||||
<listEntry value="=org.adempiere.base.process/src"/>
|
||||
<listEntry value="=org.idempiere.hazelcast.service/src"/>
|
||||
<listEntry value="=org.adempiere.eclipse.equinox.http.servlet/src"/>
|
||||
<listEntry value="=org.adempiere.replication.server/src"/>
|
||||
<listEntry value="=org.adempiere.server/src\/main\/servlet"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value="=org.idempiere.test"/>
|
||||
<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/>
|
||||
<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/>
|
||||
<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit5"/>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_ATTR_USE_ARGFILE" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value=""/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -consoleLog"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.idempiere.test"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea -Djunit.jupiter.execution.parallel.enabled=true -Djunit.jupiter.execution.parallel.mode.default=concurrent -Djunit.jupiter.execution.parallel.config.strategy=fixed -Djunit.jupiter.execution.parallel.config.fixed.parallelism=2"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${project_loc:org.adempiere.base}/.."/>
|
||||
<stringAttribute key="pde.version" value="3.3"/>
|
||||
<stringAttribute key="product" value="org.adempiere.server.server_product"/>
|
||||
<booleanAttribute key="run_in_ui_thread" value="true"/>
|
||||
<setAttribute key="selected_target_bundles">
|
||||
<setEntry value="assertj-core@default:default"/>
|
||||
<setEntry value="bcmail@default:default"/>
|
||||
<setEntry value="bcpg*1.69.0@default:default"/>
|
||||
<setEntry value="bcpkix@default:default"/>
|
||||
<setEntry value="bcprov@default:default"/>
|
||||
<setEntry value="bctsp@default:default"/>
|
||||
<setEntry value="bcutil@default:default"/>
|
||||
<setEntry value="com.diffplug.osgi.extension.sun.misc@default:false"/>
|
||||
<setEntry value="com.fasterxml.jackson.core.jackson-annotations@default:default"/>
|
||||
<setEntry value="com.fasterxml.jackson.core.jackson-core@default:default"/>
|
||||
<setEntry value="com.fasterxml.jackson.core.jackson-databind@default:default"/>
|
||||
<setEntry value="com.fasterxml.jackson.dataformat.jackson-dataformat-xml@default:default"/>
|
||||
<setEntry value="com.fasterxml.jackson.datatype.jackson-datatype-guava@default:default"/>
|
||||
<setEntry value="com.fasterxml.jackson.datatype.jackson-datatype-joda@default:default"/>
|
||||
<setEntry value="com.fasterxml.jackson.datatype.jackson-datatype-json-org@default:default"/>
|
||||
<setEntry value="com.fasterxml.jackson.jaxrs.jackson-jaxrs-base@default:default"/>
|
||||
<setEntry value="com.fasterxml.jackson.jaxrs.jackson-jaxrs-json-provider@default:default"/>
|
||||
<setEntry value="com.fasterxml.jackson.jaxrs.jackson-jaxrs-xml-provider@default:default"/>
|
||||
<setEntry value="com.fasterxml.jackson.module.jackson-module-jaxb-annotations@default:default"/>
|
||||
<setEntry value="com.fasterxml.jackson.module.jackson-module-jsonSchema@default:default"/>
|
||||
<setEntry value="com.fasterxml.woodstox.woodstox-core@default:default"/>
|
||||
<setEntry value="com.github.librepdf.openpdf-fonts-extra@default:default"/>
|
||||
<setEntry value="com.github.librepdf.openpdf@default:default"/>
|
||||
<setEntry value="com.google.gson@default:default"/>
|
||||
<setEntry value="com.google.guava.failureaccess@default:default"/>
|
||||
<setEntry value="com.google.guava@default:default"/>
|
||||
<setEntry value="com.google.http-client.google-http-client@default:default"/>
|
||||
<setEntry value="com.google.oauth-client@default:default"/>
|
||||
<setEntry value="com.google.zxing.core@default:default"/>
|
||||
<setEntry value="com.ibm.icu@default:default"/>
|
||||
<setEntry value="com.jaspersoft.studio.bundles.barbecue@default:default"/>
|
||||
<setEntry value="com.jaspersoft.studio.bundles.itext@default:default"/>
|
||||
<setEntry value="com.sun.activation.jakarta.activation@default:default"/>
|
||||
<setEntry value="com.sun.mail.gimap@default:default"/>
|
||||
<setEntry value="com.sun.mail.jakarta.mail@default:default"/>
|
||||
<setEntry value="com.sun.xml.bind.jaxb-impl@default:default"/>
|
||||
<setEntry value="com.sun.xml.fastinfoset.FastInfoset*2.0.0@default:default"/>
|
||||
<setEntry value="com.sun.xml.messaging.saaj.impl@default:default"/>
|
||||
<setEntry value="com.sun.xml.stream.buffer.streambuffer@default:default"/>
|
||||
<setEntry value="groovy-console@default:false"/>
|
||||
<setEntry value="groovy-datetime@default:false"/>
|
||||
<setEntry value="groovy-json@default:false"/>
|
||||
<setEntry value="groovy-jsr223@default:false"/>
|
||||
<setEntry value="groovy-nio@default:false"/>
|
||||
<setEntry value="groovy-sql@default:false"/>
|
||||
<setEntry value="groovy-xml@default:false"/>
|
||||
<setEntry value="groovy@default:default"/>
|
||||
<setEntry value="io.github.classgraph.classgraph@default:default"/>
|
||||
<setEntry value="jakarta.annotation-api@default:default"/>
|
||||
<setEntry value="jakarta.jws-api@default:default"/>
|
||||
<setEntry value="jakarta.persistence-api@default:default"/>
|
||||
<setEntry value="jakarta.transaction-api@default:default"/>
|
||||
<setEntry value="jakarta.validation.jakarta.validation-api@default:default"/>
|
||||
<setEntry value="jakarta.ws.rs-api@default:default"/>
|
||||
<setEntry value="jakarta.xml.bind-api@default:default"/>
|
||||
<setEntry value="jakarta.xml.soap-api@default:default"/>
|
||||
<setEntry value="jakarta.xml.ws-api@default:default"/>
|
||||
<setEntry value="javax.enterprise.cdi-api@default:default"/>
|
||||
<setEntry value="javax.interceptor-api@default:default"/>
|
||||
<setEntry value="javax.validation.api@default:default"/>
|
||||
<setEntry value="javax.websocket-api@default:default"/>
|
||||
<setEntry value="joda-time@default:default"/>
|
||||
<setEntry value="json@default:default"/>
|
||||
<setEntry value="net.sf.jasperreports.engine@default:default"/>
|
||||
<setEntry value="net.sf.supercsv.super-csv@default:default"/>
|
||||
<setEntry value="org.antlr.antlr4-runtime@default:default"/>
|
||||
<setEntry value="org.apache.activemq.activemq-client@default:default"/>
|
||||
<setEntry value="org.apache.ant@default:default"/>
|
||||
<setEntry value="org.apache.aries.spifly.dynamic.bundle@default:default"/>
|
||||
<setEntry value="org.apache.aries.util@default:default"/>
|
||||
<setEntry value="org.apache.commons.collections@default:default"/>
|
||||
<setEntry value="org.apache.commons.commons-beanutils@default:default"/>
|
||||
<setEntry value="org.apache.commons.commons-codec@default:default"/>
|
||||
<setEntry value="org.apache.commons.commons-collections4@default:default"/>
|
||||
<setEntry value="org.apache.commons.commons-compress@default:default"/>
|
||||
<setEntry value="org.apache.commons.commons-configuration2@default:default"/>
|
||||
<setEntry value="org.apache.commons.commons-fileupload@default:default"/>
|
||||
<setEntry value="org.apache.commons.commons-io@default:default"/>
|
||||
<setEntry value="org.apache.commons.commons-net@default:default"/>
|
||||
<setEntry value="org.apache.commons.commons-text@default:default"/>
|
||||
<setEntry value="org.apache.commons.digester@default:default"/>
|
||||
<setEntry value="org.apache.commons.discovery@default:default"/>
|
||||
<setEntry value="org.apache.commons.lang3@default:default"/>
|
||||
<setEntry value="org.apache.commons.lang@default:default"/>
|
||||
<setEntry value="org.apache.commons.logging@default:default"/>
|
||||
<setEntry value="org.apache.cxf.cxf-core@default:default"/>
|
||||
<setEntry value="org.apache.cxf.cxf-rt-bindings-soap@default:default"/>
|
||||
<setEntry value="org.apache.cxf.cxf-rt-bindings-xml@default:default"/>
|
||||
<setEntry value="org.apache.cxf.cxf-rt-databinding-jaxb@default:default"/>
|
||||
<setEntry value="org.apache.cxf.cxf-rt-databinding-xmlbeans@default:default"/>
|
||||
<setEntry value="org.apache.cxf.cxf-rt-frontend-jaxrs@default:default"/>
|
||||
<setEntry value="org.apache.cxf.cxf-rt-frontend-jaxws@default:default"/>
|
||||
<setEntry value="org.apache.cxf.cxf-rt-frontend-simple@default:default"/>
|
||||
<setEntry value="org.apache.cxf.cxf-rt-rs-extension-providers@default:default"/>
|
||||
<setEntry value="org.apache.cxf.cxf-rt-rs-service-description@default:default"/>
|
||||
<setEntry value="org.apache.cxf.cxf-rt-security@default:default"/>
|
||||
<setEntry value="org.apache.cxf.cxf-rt-transports-http@default:default"/>
|
||||
<setEntry value="org.apache.cxf.cxf-rt-ws-addr@default:default"/>
|
||||
<setEntry value="org.apache.cxf.cxf-rt-ws-policy@default:default"/>
|
||||
<setEntry value="org.apache.cxf.cxf-rt-wsdl@default:default"/>
|
||||
<setEntry value="org.apache.felix.gogo.command@default:default"/>
|
||||
<setEntry value="org.apache.felix.gogo.runtime@default:default"/>
|
||||
<setEntry value="org.apache.felix.gogo.shell@default:default"/>
|
||||
<setEntry value="org.apache.felix.scr@1:true"/>
|
||||
<setEntry value="org.apache.geronimo.specs.geronimo-j2ee-management_1.1_spec@default:default"/>
|
||||
<setEntry value="org.apache.geronimo.specs.geronimo-jms_1.1_spec@default:default"/>
|
||||
<setEntry value="org.apache.httpcomponents.client5.httpclient5@default:default"/>
|
||||
<setEntry value="org.apache.httpcomponents.core5.httpcore5-h2@default:default"/>
|
||||
<setEntry value="org.apache.httpcomponents.core5.httpcore5@default:default"/>
|
||||
<setEntry value="org.apache.httpcomponents.httpclient@default:default"/>
|
||||
<setEntry value="org.apache.httpcomponents.httpcore@default:default"/>
|
||||
<setEntry value="org.apache.neethi@default:default"/>
|
||||
<setEntry value="org.apache.poi.ooxml-schemas@default:default"/>
|
||||
<setEntry value="org.apache.servicemix.bundles.batik@default:default"/>
|
||||
<setEntry value="org.apache.servicemix.bundles.cglib@default:default"/>
|
||||
<setEntry value="org.apache.servicemix.bundles.jaxen@default:default"/>
|
||||
<setEntry value="org.apache.servicemix.bundles.rhino@default:default"/>
|
||||
<setEntry value="org.apache.servicemix.bundles.xerces@default:default"/>
|
||||
<setEntry value="org.apache.taglibs.standard-impl@default:default"/>
|
||||
<setEntry value="org.apache.taglibs.taglibs-standard-spec@default:default"/>
|
||||
<setEntry value="org.apache.ws.xmlschema.core@default:default"/>
|
||||
<setEntry value="org.apache.xalan@default:default"/>
|
||||
<setEntry value="org.apache.xml.resolver@default:default"/>
|
||||
<setEntry value="org.apache.xml.serializer@default:default"/>
|
||||
<setEntry value="org.apiguardian@default:default"/>
|
||||
<setEntry value="org.atmosphere.runtime@default:default"/>
|
||||
<setEntry value="org.codehaus.jettison.jettison@default:default"/>
|
||||
<setEntry value="org.cryptacular@default:default"/>
|
||||
<setEntry value="org.eclipse.ant.core@default:default"/>
|
||||
<setEntry value="org.eclipse.core.commands@default:default"/>
|
||||
<setEntry value="org.eclipse.core.contenttype@default:default"/>
|
||||
<setEntry value="org.eclipse.core.expressions@default:default"/>
|
||||
<setEntry value="org.eclipse.core.filesystem@default:default"/>
|
||||
<setEntry value="org.eclipse.core.jobs@default:default"/>
|
||||
<setEntry value="org.eclipse.core.net@default:default"/>
|
||||
<setEntry value="org.eclipse.core.resources@default:default"/>
|
||||
<setEntry value="org.eclipse.core.runtime@default:true"/>
|
||||
<setEntry value="org.eclipse.core.variables@default:default"/>
|
||||
<setEntry value="org.eclipse.ecf.filetransfer@default:default"/>
|
||||
<setEntry value="org.eclipse.ecf.identity@default:default"/>
|
||||
<setEntry value="org.eclipse.ecf.provider.filetransfer.httpclient5@default:default"/>
|
||||
<setEntry value="org.eclipse.ecf.provider.filetransfer.ssl@default:false"/>
|
||||
<setEntry value="org.eclipse.ecf.provider.filetransfer@default:default"/>
|
||||
<setEntry value="org.eclipse.ecf@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.app@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.cm@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.common@2:true"/>
|
||||
<setEntry value="org.eclipse.equinox.concurrent@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.console@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.event@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.frameworkadmin.equinox@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.frameworkadmin@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.http.registry@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.http.servlet@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.http.servletbridge@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.metatype@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.p2.artifact.repository@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.p2.console@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.p2.core@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.p2.director.app@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.p2.director@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.p2.engine@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.p2.garbagecollector@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.p2.jarprocessor@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.p2.metadata.repository@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.p2.metadata@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.p2.repository@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.p2.touchpoint.eclipse@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.p2.touchpoint.natives@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.p2.transport.ecf@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.preferences@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.registry@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.security@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.servletbridge@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.simpleconfigurator.manipulator@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.simpleconfigurator@1:true"/>
|
||||
<setEntry value="org.eclipse.jdt.core@default:default"/>
|
||||
<setEntry value="org.eclipse.jdt.junit.runtime@default:default"/>
|
||||
<setEntry value="org.eclipse.jdt.junit5.runtime@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.annotations@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.apache-jsp@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.deploy@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.http@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.io@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.jaas@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.jmx@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.jndi@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.osgi.boot.jsp@default:false"/>
|
||||
<setEntry value="org.eclipse.jetty.osgi.boot@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.osgi.httpservice@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.plus@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.security@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.server@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.servlet-api@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.servlet@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.servlets@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.util.ajax@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.util@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.webapp@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.websocket.api@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.websocket.common@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.websocket.core.common@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.websocket.core.server@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.websocket.server@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.websocket.servlet@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.xml@default:default"/>
|
||||
<setEntry value="org.eclipse.osgi.compatibility.state@default:false"/>
|
||||
<setEntry value="org.eclipse.osgi.services@default:default"/>
|
||||
<setEntry value="org.eclipse.osgi.util@default:default"/>
|
||||
<setEntry value="org.eclipse.osgi@-1:true"/>
|
||||
<setEntry value="org.eclipse.text@default:default"/>
|
||||
<setEntry value="org.fusesource.hawtbuf.hawtbuf@default:default"/>
|
||||
<setEntry value="org.glassfish.external.management-api@default:default"/>
|
||||
<setEntry value="org.glassfish.gmbal.gmbal@default:default"/>
|
||||
<setEntry value="org.glassfish.hk2.api@default:default"/>
|
||||
<setEntry value="org.glassfish.hk2.external.aopalliance-repackaged@default:default"/>
|
||||
<setEntry value="org.glassfish.hk2.external.jakarta.inject@default:default"/>
|
||||
<setEntry value="org.glassfish.hk2.locator@default:default"/>
|
||||
<setEntry value="org.glassfish.hk2.osgi-resource-locator@default:default"/>
|
||||
<setEntry value="org.glassfish.hk2.utils@default:default"/>
|
||||
<setEntry value="org.glassfish.jersey.core.jersey-client@default:default"/>
|
||||
<setEntry value="org.glassfish.jersey.core.jersey-common@default:default"/>
|
||||
<setEntry value="org.glassfish.jersey.core.jersey-server@default:default"/>
|
||||
<setEntry value="org.glassfish.jersey.ext.jersey-entity-filtering@default:default"/>
|
||||
<setEntry value="org.glassfish.jersey.media.jersey-media-json-jackson@default:default"/>
|
||||
<setEntry value="org.glassfish.pfl.pfl-asm@default:default"/>
|
||||
<setEntry value="org.glassfish.pfl.pfl-basic@default:default"/>
|
||||
<setEntry value="org.glassfish.pfl.pfl-dynamic@default:default"/>
|
||||
<setEntry value="org.glassfish.pfl.pfl-tf@default:default"/>
|
||||
<setEntry value="org.hamcrest.core@default:default"/>
|
||||
<setEntry value="org.jsr-305@default:default"/>
|
||||
<setEntry value="org.junit.jupiter.api@default:default"/>
|
||||
<setEntry value="org.junit.jupiter.engine@default:default"/>
|
||||
<setEntry value="org.junit.jupiter.migrationsupport@default:default"/>
|
||||
<setEntry value="org.junit.jupiter.params@default:default"/>
|
||||
<setEntry value="org.junit.platform.commons@default:default"/>
|
||||
<setEntry value="org.junit.platform.engine@default:default"/>
|
||||
<setEntry value="org.junit.platform.launcher@default:default"/>
|
||||
<setEntry value="org.junit.platform.runner@default:default"/>
|
||||
<setEntry value="org.junit.platform.suite.api@default:default"/>
|
||||
<setEntry value="org.junit.platform.suite.commons@default:default"/>
|
||||
<setEntry value="org.junit.platform.suite.engine@default:default"/>
|
||||
<setEntry value="org.junit.vintage.engine@default:default"/>
|
||||
<setEntry value="org.junit@default:default"/>
|
||||
<setEntry value="org.jvnet.mimepull@default:default"/>
|
||||
<setEntry value="org.jvnet.staxex.stax-ex@default:default"/>
|
||||
<setEntry value="org.krysalis.barcode4j@default:default"/>
|
||||
<setEntry value="org.mortbay.jasper.apache-el@default:default"/>
|
||||
<setEntry value="org.mortbay.jasper.apache-jsp@default:default"/>
|
||||
<setEntry value="org.objectweb.asm.commons@default:default"/>
|
||||
<setEntry value="org.objectweb.asm.tree.analysis@default:default"/>
|
||||
<setEntry value="org.objectweb.asm.tree@default:default"/>
|
||||
<setEntry value="org.objectweb.asm.util@default:default"/>
|
||||
<setEntry value="org.objectweb.asm@default:default"/>
|
||||
<setEntry value="org.opentest4j@default:default"/>
|
||||
<setEntry value="org.passay@default:default"/>
|
||||
<setEntry value="org.sat4j.core@default:default"/>
|
||||
<setEntry value="org.sat4j.pb@default:default"/>
|
||||
<setEntry value="org.tukaani.xz@default:default"/>
|
||||
<setEntry value="org.w3c.css.sac@default:default"/>
|
||||
<setEntry value="org.w3c.dom.events@default:default"/>
|
||||
<setEntry value="org.w3c.dom.smil@default:default"/>
|
||||
<setEntry value="org.w3c.dom.svg@default:default"/>
|
||||
<setEntry value="org.zkoss.zsoup@default:default"/>
|
||||
<setEntry value="slf4j.api*1.7.30@default:default"/>
|
||||
<setEntry value="slf4j.jcl@default:false"/>
|
||||
<setEntry value="stax2-api@default:default"/>
|
||||
<setEntry value="wrapped.com.google.http-client.google-http-client-gson@default:default"/>
|
||||
<setEntry value="wrapped.com.google.zxing.javase@default:default"/>
|
||||
<setEntry value="wrapped.com.sun.org.apache.xml.internal.resolver@default:default"/>
|
||||
<setEntry value="wrapped.com.zaxxer.SparseBitSet@default:default"/>
|
||||
<setEntry value="wrapped.dev.samstevens.totp.totp@default:default"/>
|
||||
<setEntry value="wrapped.io.grpc.grpc-context@default:default"/>
|
||||
<setEntry value="wrapped.io.opencensus.opencensus-api@default:default"/>
|
||||
<setEntry value="wrapped.io.opencensus.opencensus-contrib-http-util@default:default"/>
|
||||
<setEntry value="wrapped.org.apache.activemq.activemq-kahadb-store@default:default"/>
|
||||
<setEntry value="wrapped.org.apache.poi.poi-ooxml@default:default"/>
|
||||
<setEntry value="wrapped.org.apache.poi.poi@default:default"/>
|
||||
<setEntry value="wrapped.org.apache.xmlbeans.xmlbeans@default:default"/>
|
||||
<setEntry value="wrapped.org.apache.xmlgraphics.xmlgraphics-commons@default:default"/>
|
||||
<setEntry value="wrapped.org.dom4j.dom4j@default:default"/>
|
||||
<setEntry value="wrapped.org.glassfish.jaxb.txw2@default:default"/>
|
||||
<setEntry value="wrapped.org.jfree.jcommon@default:default"/>
|
||||
<setEntry value="wrapped.org.jfree.jfreechart@default:default"/>
|
||||
<setEntry value="wrapped.org.springframework.spring-aop@default:default"/>
|
||||
<setEntry value="wrapped.org.springframework.spring-beans@default:default"/>
|
||||
<setEntry value="wrapped.org.springframework.spring-context-support@default:default"/>
|
||||
<setEntry value="wrapped.org.springframework.spring-context@default:default"/>
|
||||
<setEntry value="wrapped.org.springframework.spring-core@default:default"/>
|
||||
<setEntry value="wrapped.org.springframework.spring-expression@default:default"/>
|
||||
<setEntry value="wrapped.org.springframework.spring-web@default:default"/>
|
||||
<setEntry value="wrapped.wsdl4j.wsdl4j@default:default"/>
|
||||
<setEntry value="xstream@default:default"/>
|
||||
<setEntry value="zcommon@default:default"/>
|
||||
<setEntry value="zel@default:default"/>
|
||||
<setEntry value="zhtml@default:default"/>
|
||||
<setEntry value="zjavassist@default:default"/>
|
||||
<setEntry value="zk@default:default"/>
|
||||
<setEntry value="zkbind@default:default"/>
|
||||
<setEntry value="zkplus@default:default"/>
|
||||
<setEntry value="zkwebfragment@default:default"/>
|
||||
<setEntry value="zul@default:default"/>
|
||||
<setEntry value="zweb-dsp@default:false"/>
|
||||
<setEntry value="zweb@default:default"/>
|
||||
</setAttribute>
|
||||
<setAttribute key="selected_workspace_bundles">
|
||||
<setEntry value="org.adempiere.base.callout@default:default"/>
|
||||
<setEntry value="org.adempiere.base.process@default:default"/>
|
||||
<setEntry value="org.adempiere.base@default:default"/>
|
||||
<setEntry value="org.adempiere.eclipse.equinox.http.servlet@default:default"/>
|
||||
<setEntry value="org.adempiere.install@default:default"/>
|
||||
<setEntry value="org.adempiere.payment.processor@default:default"/>
|
||||
<setEntry value="org.adempiere.pipo.handlers@default:default"/>
|
||||
<setEntry value="org.adempiere.pipo@default:true"/>
|
||||
<setEntry value="org.adempiere.plugin.utils@default:default"/>
|
||||
<setEntry value="org.adempiere.replication@default:default"/>
|
||||
<setEntry value="org.adempiere.report.jasper.library@default:false"/>
|
||||
<setEntry value="org.adempiere.report.jasper@default:default"/>
|
||||
<setEntry value="org.adempiere.server@default:default"/>
|
||||
<setEntry value="org.adempiere.ui.zk@default:default"/>
|
||||
<setEntry value="org.adempiere.ui@default:default"/>
|
||||
<setEntry value="org.apache.ecs@default:default"/>
|
||||
<setEntry value="org.compiere.db.oracle.provider@default:default"/>
|
||||
<setEntry value="org.compiere.db.postgresql.provider@default:default"/>
|
||||
<setEntry value="org.idempiere.hazelcast.service@default:default"/>
|
||||
<setEntry value="org.idempiere.test@default:default"/>
|
||||
<setEntry value="org.idempiere.webservices@default:default"/>
|
||||
<setEntry value="org.idempiere.zk.extra@default:default"/>
|
||||
</setAttribute>
|
||||
<booleanAttribute key="show_selected_only" value="false"/>
|
||||
<stringAttribute key="templateConfig" value="${target_home}/configuration/config.ini"/>
|
||||
<booleanAttribute key="tracing" value="false"/>
|
||||
<booleanAttribute key="useCustomFeatures" value="false"/>
|
||||
<booleanAttribute key="useDefaultConfig" value="true"/>
|
||||
<booleanAttribute key="useDefaultConfigArea" value="false"/>
|
||||
<booleanAttribute key="useProduct" value="false"/>
|
||||
</launchConfiguration>
|
|
@ -0,0 +1,89 @@
|
|||
/***********************************************************************
|
||||
* This file is part of iDempiere ERP Open Source *
|
||||
* http://www.idempiere.org *
|
||||
* *
|
||||
* Copyright (C) Contributors *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software *
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
|
||||
* MA 02110-1301, USA. *
|
||||
* *
|
||||
* Contributors: *
|
||||
* - hengsin *
|
||||
**********************************************************************/
|
||||
package org.idempiere.test;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.Timestamp;
|
||||
|
||||
import org.compiere.model.MConversionRate;
|
||||
import org.compiere.model.Query;
|
||||
import org.compiere.util.Env;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hengsin
|
||||
*
|
||||
*/
|
||||
public final class ConversionRateHelper {
|
||||
|
||||
private ConversionRateHelper() {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param C_Currency_ID
|
||||
* @param C_Currency_ID_To
|
||||
* @param C_ConversionType_ID
|
||||
* @param date
|
||||
* @param rate
|
||||
* @param isMultiplyRate
|
||||
* @return {@link MConversionRate}
|
||||
*/
|
||||
public static MConversionRate createConversionRate(int C_Currency_ID, int C_Currency_ID_To, int C_ConversionType_ID,
|
||||
Timestamp date, BigDecimal rate, boolean isMultiplyRate) {
|
||||
MConversionRate cr = new MConversionRate(Env.getCtx(), 0, null);
|
||||
cr.setC_Currency_ID(C_Currency_ID);
|
||||
cr.setC_Currency_ID_To(C_Currency_ID_To);
|
||||
cr.setC_ConversionType_ID(C_ConversionType_ID);
|
||||
cr.setValidFrom(date);
|
||||
cr.setValidTo(date);
|
||||
if (isMultiplyRate)
|
||||
cr.setMultiplyRate(rate);
|
||||
else
|
||||
cr.setDivideRate(rate);
|
||||
cr.saveEx();
|
||||
return cr;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param cr
|
||||
*/
|
||||
public static void deleteConversionRate(MConversionRate cr) {
|
||||
String whereClause = "ValidFrom=? AND ValidTo=? "
|
||||
+ "AND C_Currency_ID=? AND C_Currency_ID_To=? "
|
||||
+ "AND C_ConversionType_ID=? "
|
||||
+ "AND AD_Client_ID=? AND AD_Org_ID=?";
|
||||
MConversionRate reciprocal = new Query(Env.getCtx(), MConversionRate.Table_Name, whereClause, null)
|
||||
.setParameters(cr.getValidFrom(), cr.getValidTo(),
|
||||
cr.getC_Currency_ID_To(), cr.getC_Currency_ID(),
|
||||
cr.getC_ConversionType_ID(),
|
||||
cr.getAD_Client_ID(), cr.getAD_Org_ID())
|
||||
.firstOnly();
|
||||
if (reciprocal != null)
|
||||
reciprocal.deleteEx(true);
|
||||
cr.deleteEx(true);
|
||||
}
|
||||
}
|
|
@ -93,7 +93,12 @@ public final class DictionaryIDs {
|
|||
C_AND_W(117),
|
||||
JOE_BLOCK(118),
|
||||
SEED_FARM(120),
|
||||
PATIO(121);
|
||||
PATIO(121),
|
||||
WOOD_INC(50000),
|
||||
COLOR_INC(50001),
|
||||
CHROME_INC(50002),
|
||||
CHEMICAL_INC(50003),
|
||||
AGRI_TECH(200000);
|
||||
|
||||
public final int id;
|
||||
|
||||
|
|
|
@ -20,12 +20,15 @@ import org.compiere.util.Env;
|
|||
import org.compiere.util.Ini;
|
||||
import org.idempiere.test.AbstractTestCase;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.parallel.Execution;
|
||||
import org.junit.jupiter.api.parallel.ExecutionMode;
|
||||
|
||||
/**
|
||||
* Unit testing for Convert_PostgreSQL.
|
||||
* @author Low Heng Sin
|
||||
* @version 20061225
|
||||
*/
|
||||
@Execution(ExecutionMode.SAME_THREAD)
|
||||
public final class Convert_PostgreSQLTest extends AbstractTestCase {
|
||||
//private Convert_PostgreSQL convert = new Convert_PostgreSQL();
|
||||
String sql;
|
||||
|
|
|
@ -54,7 +54,6 @@ import org.compiere.model.MShipper;
|
|||
import org.compiere.model.MShippingProcessor;
|
||||
import org.compiere.model.MWarehouse;
|
||||
import org.compiere.model.PO;
|
||||
import org.compiere.model.Query;
|
||||
import org.compiere.model.SystemIDs;
|
||||
import org.compiere.model.X_C_BP_ShippingAcct;
|
||||
import org.compiere.model.X_M_ShippingProcessorCfg;
|
||||
|
@ -65,8 +64,10 @@ import org.compiere.util.Env;
|
|||
import org.compiere.util.TimeUtil;
|
||||
import org.compiere.wf.MWorkflow;
|
||||
import org.idempiere.test.AbstractTestCase;
|
||||
import org.idempiere.test.ConversionRateHelper;
|
||||
import org.idempiere.test.DictionaryIDs;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.parallel.ResourceLock;
|
||||
|
||||
/**
|
||||
* @author etantg
|
||||
|
@ -77,6 +78,7 @@ public class InOutTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MConversionRate.Table_Name)
|
||||
/**
|
||||
* https://idempiere.atlassian.net/browse/IDEMPIERE-4656
|
||||
*/
|
||||
|
@ -212,6 +214,7 @@ public class InOutTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MConversionRate.Table_Name)
|
||||
/**
|
||||
* https://idempiere.atlassian.net/browse/IDEMPIERE-4656
|
||||
*/
|
||||
|
@ -374,34 +377,11 @@ public class InOutTest extends AbstractTestCase {
|
|||
|
||||
private MConversionRate createConversionRate(int C_Currency_ID, int C_Currency_ID_To, int C_ConversionType_ID,
|
||||
Timestamp date, BigDecimal rate, boolean isMultiplyRate) {
|
||||
MConversionRate cr = new MConversionRate(Env.getCtx(), 0, null);
|
||||
cr.setC_Currency_ID(C_Currency_ID);
|
||||
cr.setC_Currency_ID_To(C_Currency_ID_To);
|
||||
cr.setC_ConversionType_ID(C_ConversionType_ID);
|
||||
cr.setValidFrom(date);
|
||||
cr.setValidTo(date);
|
||||
if (isMultiplyRate)
|
||||
cr.setMultiplyRate(rate);
|
||||
else
|
||||
cr.setDivideRate(rate);
|
||||
cr.saveEx();
|
||||
return cr;
|
||||
return ConversionRateHelper.createConversionRate(C_Currency_ID, C_Currency_ID_To, C_ConversionType_ID, date, rate, isMultiplyRate);
|
||||
}
|
||||
|
||||
private void deleteConversionRate(MConversionRate cr) {
|
||||
String whereClause = "ValidFrom=? AND ValidTo=? "
|
||||
+ "AND C_Currency_ID=? AND C_Currency_ID_To=? "
|
||||
+ "AND C_ConversionType_ID=? "
|
||||
+ "AND AD_Client_ID=? AND AD_Org_ID=?";
|
||||
MConversionRate reciprocal = new Query(Env.getCtx(), MConversionRate.Table_Name, whereClause, null)
|
||||
.setParameters(cr.getValidFrom(), cr.getValidTo(),
|
||||
cr.getC_Currency_ID_To(), cr.getC_Currency_ID(),
|
||||
cr.getC_ConversionType_ID(),
|
||||
cr.getAD_Client_ID(), cr.getAD_Org_ID())
|
||||
.firstOnly();
|
||||
if (reciprocal != null)
|
||||
reciprocal.deleteEx(true);
|
||||
cr.deleteEx(true);
|
||||
ConversionRateHelper.deleteConversionRate(cr);
|
||||
}
|
||||
|
||||
private MOrder createPurchaseOrder(MBPartner bpartner, Timestamp date, int M_PriceList_ID, int C_ConversionType_ID) {
|
||||
|
|
|
@ -59,15 +59,16 @@ import org.compiere.model.MProductPrice;
|
|||
import org.compiere.model.MWarehouse;
|
||||
import org.compiere.model.PO;
|
||||
import org.compiere.model.ProductCost;
|
||||
import org.compiere.model.Query;
|
||||
import org.compiere.process.DocAction;
|
||||
import org.compiere.process.DocumentEngine;
|
||||
import org.compiere.process.ProcessInfo;
|
||||
import org.compiere.util.Env;
|
||||
import org.compiere.wf.MWorkflow;
|
||||
import org.idempiere.test.AbstractTestCase;
|
||||
import org.idempiere.test.ConversionRateHelper;
|
||||
import org.idempiere.test.DictionaryIDs;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.parallel.ResourceLock;
|
||||
|
||||
/**
|
||||
* @author Elaine Tan - etantg
|
||||
|
@ -78,6 +79,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MConversionRate.Table_Name)
|
||||
/**
|
||||
* Test the matched invoice posting for credit memo (same period)
|
||||
* PO Qty1=2400, Qty2=2400
|
||||
|
@ -167,6 +169,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MConversionRate.Table_Name)
|
||||
/**
|
||||
* Test the matched invoice posting for credit memo (same period)
|
||||
* PO Qty=10, Price=33.75
|
||||
|
@ -177,7 +180,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase {
|
|||
* IV Qty=5
|
||||
*/
|
||||
public void testCreditMemoPosting_2() {
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.TREE_FARM.id); // Tree Farm Inc.
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.CHEMICAL_INC.id);
|
||||
MProduct product = MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.ELM.id); // Elm Tree
|
||||
Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date");
|
||||
int C_ConversionType_ID = DictionaryIDs.C_ConversionType.COMPANY.id; // Company
|
||||
|
@ -284,6 +287,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MConversionRate.Table_Name)
|
||||
/**
|
||||
* Test the matched invoice posting for credit memo (different period)
|
||||
* PO Qty=3, Price=0.3023, Period 1
|
||||
|
@ -292,7 +296,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase {
|
|||
* CM Qty=2, Period 2
|
||||
*/
|
||||
public void testCreditMemoPosting_3() {
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.TREE_FARM.id); // Tree Farm Inc.
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.WOOD_INC.id);
|
||||
MProduct product = MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.ELM.id); // Elm Tree
|
||||
Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date");
|
||||
|
||||
|
@ -409,6 +413,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MConversionRate.Table_Name)
|
||||
/**
|
||||
* Test the matched invoice posting for credit memo (different period)
|
||||
* PO Qty1=1000, Qty2=1000, Qty3=1000, Price1=3.00, Price2=2.70, Price3=3.15, Period 1
|
||||
|
@ -417,7 +422,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase {
|
|||
* CM Qty1=200, Qty2=300, Period 3
|
||||
*/
|
||||
public void testCreditMemoPosting_4() {
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.TREE_FARM.id); // Tree Farm Inc.
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.CHEMICAL_INC.id);
|
||||
MProduct product1 = MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.ELM.id); // Elm Tree
|
||||
MProduct product2 = MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.OAK.id); // Oak Tree
|
||||
MProduct product3 = MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.PLUM_TREE.id); // Plum Tree
|
||||
|
@ -582,6 +587,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MConversionRate.Table_Name)
|
||||
/**
|
||||
* Test the matched invoice posting for credit memo (same period)
|
||||
* PO Qty=2, Price=0.1875
|
||||
|
@ -590,7 +596,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase {
|
|||
* CM Qty=1
|
||||
*/
|
||||
public void testCreditMemoPosting_5() {
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.TREE_FARM.id); // Tree Farm Inc.
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.WOOD_INC.id);
|
||||
MProduct product = MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.ELM.id); // Elm Tree
|
||||
Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date");
|
||||
int C_ConversionType_ID = DictionaryIDs.C_ConversionType.COMPANY.id; // Company
|
||||
|
@ -670,6 +676,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MConversionRate.Table_Name)
|
||||
/**
|
||||
* Test the matched invoice posting for credit memo (same period)
|
||||
* PO Qty=200, Price=0.1875
|
||||
|
@ -758,6 +765,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MConversionRate.Table_Name)
|
||||
/**
|
||||
* Test the matched invoice posting for credit memo (same period)
|
||||
* PO Qty=45, Price=0.3742
|
||||
|
@ -766,7 +774,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase {
|
|||
* CM Qty=44
|
||||
*/
|
||||
public void testCreditMemoPosting_7() {
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.TREE_FARM.id); // Tree Farm Inc.
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.CHEMICAL_INC.id);
|
||||
MProduct product = MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.ELM.id); // Elm Tree
|
||||
Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date");
|
||||
int C_ConversionType_ID = DictionaryIDs.C_ConversionType.COMPANY.id; // Company
|
||||
|
@ -844,6 +852,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MConversionRate.Table_Name)
|
||||
/**
|
||||
* Test the matched invoice posting for credit memo (same period + reversal)
|
||||
* PO Qty=2, Price=0.1875
|
||||
|
@ -854,7 +863,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase {
|
|||
* CM Qty=1
|
||||
*/
|
||||
public void testCreditMemoPosting_8() {
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.TREE_FARM.id); // Tree Farm Inc.
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.WOOD_INC.id);
|
||||
MProduct product = MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.ELM.id); // Elm Tree
|
||||
Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date");
|
||||
int C_ConversionType_ID = DictionaryIDs.C_ConversionType.COMPANY.id; // Company
|
||||
|
@ -977,6 +986,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MConversionRate.Table_Name)
|
||||
/**
|
||||
* Test the matched invoice posting (same period)
|
||||
* PO Qty=1200, Price=0.3742
|
||||
|
@ -985,7 +995,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase {
|
|||
* MR Qty=1200
|
||||
*/
|
||||
public void testMatReceiptPosting_1() {
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.TREE_FARM.id); // Tree Farm Inc.
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.CHEMICAL_INC.id);
|
||||
MProduct product = MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.ELM.id); // Elm Tree
|
||||
Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date");
|
||||
int C_ConversionType_ID = DictionaryIDs.C_ConversionType.COMPANY.id; // Company
|
||||
|
@ -1063,6 +1073,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MConversionRate.Table_Name)
|
||||
/**
|
||||
* Test the matched invoice posting (different period)
|
||||
* PO Qty=1200, Price=0.3742, Period 1
|
||||
|
@ -1071,7 +1082,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase {
|
|||
* MR Qty=44, Period 2
|
||||
*/
|
||||
public void testMatReceiptPosting_2() {
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.TREE_FARM.id); // Tree Farm Inc.
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.WOOD_INC.id);
|
||||
MProduct product = MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.ELM.id); // Elm Tree
|
||||
Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date");
|
||||
|
||||
|
@ -1160,6 +1171,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MConversionRate.Table_Name)
|
||||
/**
|
||||
* Test the matched invoice posting (same period + reversal)
|
||||
* PO Qty=2, Price=0.1875
|
||||
|
@ -1293,6 +1305,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MConversionRate.Table_Name)
|
||||
/**
|
||||
* Test the matched invoice posting (different period + reversal)
|
||||
* PO Qty=2, Price=0.1875, Period 1
|
||||
|
@ -1303,7 +1316,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase {
|
|||
* MR Qty=1, Period 2
|
||||
*/
|
||||
public void testMatReceiptPosting_4() {
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.TREE_FARM.id); // Tree Farm Inc.
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.WOOD_INC.id);
|
||||
MProduct product = MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.ELM.id); // Elm Tree
|
||||
Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date");
|
||||
|
||||
|
@ -1437,6 +1450,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MConversionRate.Table_Name)
|
||||
/**
|
||||
* Test the matched invoice posting (same period)
|
||||
* PO Qty=500, Price=23.32
|
||||
|
@ -1445,7 +1459,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase {
|
|||
* IV Qty=250
|
||||
*/
|
||||
public void testMatReceiptPosting_5() {
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.TREE_FARM.id); // Tree Farm Inc.
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.CHEMICAL_INC.id);
|
||||
MProduct product = MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.ELM.id); // Elm Tree
|
||||
Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date");
|
||||
|
||||
|
@ -1549,6 +1563,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MConversionRate.Table_Name)
|
||||
/**
|
||||
* Test the matched invoice posting (same period + reversal)
|
||||
* PO Qty=5, Price=65
|
||||
|
@ -1557,7 +1572,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase {
|
|||
* MR Qty=5 (Reversed)
|
||||
*/
|
||||
public void testMatReceiptPostingWithDiffCurrencyPrecision() {
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.TREE_FARM.id); // Tree Farm Inc.
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.CHEMICAL_INC.id);
|
||||
MProduct product = MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.ELM.id); // Elm Tree
|
||||
Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date");
|
||||
|
||||
|
@ -1658,34 +1673,11 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase {
|
|||
|
||||
private MConversionRate createConversionRate(int C_Currency_ID, int C_Currency_ID_To, int C_ConversionType_ID,
|
||||
Timestamp date, BigDecimal rate, boolean isMultiplyRate) {
|
||||
MConversionRate cr = new MConversionRate(Env.getCtx(), 0, null);
|
||||
cr.setC_Currency_ID(C_Currency_ID);
|
||||
cr.setC_Currency_ID_To(C_Currency_ID_To);
|
||||
cr.setC_ConversionType_ID(C_ConversionType_ID);
|
||||
cr.setValidFrom(date);
|
||||
cr.setValidTo(date);
|
||||
if (isMultiplyRate)
|
||||
cr.setMultiplyRate(rate);
|
||||
else
|
||||
cr.setDivideRate(rate);
|
||||
cr.saveEx();
|
||||
return cr;
|
||||
return ConversionRateHelper.createConversionRate(C_Currency_ID, C_Currency_ID_To, C_ConversionType_ID, date, rate, isMultiplyRate);
|
||||
}
|
||||
|
||||
private void deleteConversionRate(MConversionRate cr) {
|
||||
String whereClause = "ValidFrom=? AND ValidTo=? "
|
||||
+ "AND C_Currency_ID=? AND C_Currency_ID_To=? "
|
||||
+ "AND C_ConversionType_ID=? "
|
||||
+ "AND AD_Client_ID=? AND AD_Org_ID=?";
|
||||
MConversionRate reciprocal = new Query(Env.getCtx(), MConversionRate.Table_Name, whereClause, null)
|
||||
.setParameters(cr.getValidFrom(), cr.getValidTo(),
|
||||
cr.getC_Currency_ID_To(), cr.getC_Currency_ID(),
|
||||
cr.getC_ConversionType_ID(),
|
||||
cr.getAD_Client_ID(), cr.getAD_Org_ID())
|
||||
.firstOnly();
|
||||
if (reciprocal != null)
|
||||
reciprocal.deleteEx(true);
|
||||
cr.deleteEx(true);
|
||||
ConversionRateHelper.deleteConversionRate(cr);
|
||||
}
|
||||
|
||||
private MOrder createPurchaseOrder(MBPartner bpartner, Timestamp date, int M_PriceList_ID, int C_ConversionType_ID) {
|
||||
|
|
|
@ -26,13 +26,11 @@ package org.idempiere.test.base;
|
|||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.List;
|
||||
|
||||
import org.compiere.acct.Doc;
|
||||
import org.compiere.acct.DocManager;
|
||||
|
@ -41,14 +39,11 @@ import org.compiere.model.MAcctSchema;
|
|||
import org.compiere.model.MBPartner;
|
||||
import org.compiere.model.MClient;
|
||||
import org.compiere.model.MConversionRate;
|
||||
import org.compiere.model.MCost;
|
||||
import org.compiere.model.MCurrency;
|
||||
import org.compiere.model.MDocType;
|
||||
import org.compiere.model.MFactAcct;
|
||||
import org.compiere.model.MInOut;
|
||||
import org.compiere.model.MInOutLine;
|
||||
import org.compiere.model.MInventory;
|
||||
import org.compiere.model.MInventoryLine;
|
||||
import org.compiere.model.MInvoice;
|
||||
import org.compiere.model.MInvoiceLine;
|
||||
import org.compiere.model.MMatchInv;
|
||||
|
@ -57,8 +52,6 @@ import org.compiere.model.MOrderLine;
|
|||
import org.compiere.model.MPriceList;
|
||||
import org.compiere.model.MPriceListVersion;
|
||||
import org.compiere.model.MProduct;
|
||||
import org.compiere.model.MProductCategory;
|
||||
import org.compiere.model.MProductCategoryAcct;
|
||||
import org.compiere.model.MProductPrice;
|
||||
import org.compiere.model.MRMA;
|
||||
import org.compiere.model.MRMALine;
|
||||
|
@ -357,187 +350,6 @@ public class MatchInvTest extends AbstractTestCase {
|
|||
rollback();
|
||||
}
|
||||
|
||||
@Test
|
||||
/**
|
||||
* Test Standard Cost and Invoice Price Variance posting
|
||||
*/
|
||||
public void testMatchInvStdCost() {
|
||||
MProductCategory category = new MProductCategory(Env.getCtx(), 0, null);
|
||||
category.setName("Standard Costing");
|
||||
category.saveEx();
|
||||
String whereClause = "M_Product_Category_ID=?";
|
||||
List<MProductCategoryAcct> categoryAccts = new Query(Env.getCtx(), MProductCategoryAcct.Table_Name, whereClause, null)
|
||||
.setParameters(category.get_ID())
|
||||
.list();
|
||||
for (MProductCategoryAcct categoryAcct : categoryAccts) {
|
||||
categoryAcct.setCostingMethod(MAcctSchema.COSTINGMETHOD_StandardCosting);
|
||||
categoryAcct.saveEx();
|
||||
}
|
||||
|
||||
try {
|
||||
int mulchId = DictionaryIDs.M_Product.MULCH.id; // Mulch product
|
||||
MProduct mulch = new MProduct(Env.getCtx(), mulchId, getTrxName());
|
||||
mulch.setM_Product_Category_ID(category.get_ID());
|
||||
mulch.saveEx();
|
||||
|
||||
int purchaseId = DictionaryIDs.M_PriceList.PURCHASE.id; // Purchase Price List
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.SEED_FARM.id); // Seed Farm Inc.
|
||||
MAcctSchema as = MClient.get(getAD_Client_ID()).getAcctSchema();
|
||||
BigDecimal mulchCost = MCost.getCurrentCost(mulch, 0, getTrxName()).setScale(as.getCostingPrecision(), RoundingMode.HALF_UP);
|
||||
|
||||
// Change standard cost of mulch product to 2.1234
|
||||
int hqLocator = DictionaryIDs.M_Locator.HQ.id;
|
||||
int costAdjustmentDocTypeId = DictionaryIDs.C_DocType.COST_ADJUSTMENT.id;
|
||||
MInventory inventory = new MInventory(Env.getCtx(), 0, getTrxName());
|
||||
inventory.setCostingMethod(MAcctSchema.COSTINGMETHOD_StandardCosting);
|
||||
inventory.setC_DocType_ID(costAdjustmentDocTypeId);
|
||||
inventory.setM_Warehouse_ID(getM_Warehouse_ID());
|
||||
inventory.setMovementDate(getLoginDate());
|
||||
inventory.setDocAction(DocAction.ACTION_Complete);
|
||||
inventory.saveEx();
|
||||
|
||||
BigDecimal endProductCost = new BigDecimal("2.1234").setScale(as.getCostingPrecision(), RoundingMode.HALF_UP);
|
||||
MInventoryLine il = new MInventoryLine(Env.getCtx(), 0, getTrxName());
|
||||
il.setM_Inventory_ID(inventory.get_ID());
|
||||
il.setM_Locator_ID(hqLocator);
|
||||
il.setM_Product_ID(mulch.getM_Product_ID());
|
||||
il.setCurrentCostPrice(mulchCost);
|
||||
il.setNewCostPrice(endProductCost);
|
||||
il.saveEx();
|
||||
|
||||
ProcessInfo info = MWorkflow.runDocumentActionWorkflow(inventory, DocAction.ACTION_Complete);
|
||||
inventory.load(getTrxName());
|
||||
assertFalse(info.isError(), info.getSummary());
|
||||
assertEquals(DocAction.STATUS_Completed, inventory.getDocStatus(), "Cost Adjustment Status="+inventory.getDocStatus());
|
||||
|
||||
if (!inventory.isPosted()) {
|
||||
String msg = DocumentEngine.postImmediate(Env.getCtx(), getAD_Client_ID(), MInventory.Table_ID, inventory.get_ID(), false, getTrxName());
|
||||
assertNull(msg, msg);
|
||||
}
|
||||
mulchCost = MCost.getCurrentCost(mulch, 0, getTrxName()).setScale(as.getCostingPrecision(), RoundingMode.HALF_UP);
|
||||
assertEquals(endProductCost, mulchCost, "Cost not adjusted: " + mulchCost.toPlainString());
|
||||
|
||||
//test converted cost for all schemas
|
||||
MAcctSchema[] schemas = MAcctSchema.getClientAcctSchema(Env.getCtx(), getAD_Client_ID());
|
||||
for (int i = 0; i < schemas.length; i++) {
|
||||
BigDecimal expected = MConversionRate.convert (Env.getCtx(),
|
||||
mulchCost, as.getC_Currency_ID(), schemas[i].getC_Currency_ID(),
|
||||
inventory.getMovementDate(), 0, getAD_Client_ID(), getAD_Org_ID(), true);
|
||||
BigDecimal mulchCostConv = MCost.getCurrentCost(mulch, 0, schemas[i], schemas[i].getAD_Org_ID(), MAcctSchema.COSTINGMETHOD_StandardCosting,
|
||||
BigDecimal.ONE, 0, true, getTrxName()).setScale(schemas[i].getCostingPrecision(), RoundingMode.HALF_UP);
|
||||
assertEquals(expected, mulchCostConv, "Converted Cost for schema incorrect: " + schemas[i].toString()+ " - " + mulchCostConv.toPlainString());
|
||||
}
|
||||
|
||||
MOrder order = new MOrder(Env.getCtx(), 0, getTrxName());
|
||||
order.setBPartner(bpartner);
|
||||
order.setIsSOTrx(false);
|
||||
order.setC_DocTypeTarget_ID();
|
||||
order.setM_PriceList_ID(purchaseId);
|
||||
order.setDocStatus(DocAction.STATUS_Drafted);
|
||||
order.setDocAction(DocAction.ACTION_Complete);
|
||||
order.saveEx();
|
||||
|
||||
MOrderLine orderLine = new MOrderLine(order);
|
||||
orderLine.setLine(10);
|
||||
orderLine.setProduct(mulch);
|
||||
orderLine.setQty(BigDecimal.ONE);
|
||||
orderLine.saveEx();
|
||||
|
||||
info = MWorkflow.runDocumentActionWorkflow(order, DocAction.ACTION_Complete);
|
||||
order.load(getTrxName());
|
||||
assertFalse(info.isError(), info.getSummary());
|
||||
assertEquals(DocAction.STATUS_Completed, order.getDocStatus());
|
||||
|
||||
MInOut receipt = new MInOut(order, 122, order.getDateOrdered()); // MM Receipt
|
||||
receipt.saveEx();
|
||||
|
||||
MInOutLine receiptLine = new MInOutLine(receipt);
|
||||
receiptLine.setC_OrderLine_ID(orderLine.get_ID());
|
||||
receiptLine.setLine(10);
|
||||
receiptLine.setProduct(mulch);
|
||||
receiptLine.setQty(BigDecimal.ONE);
|
||||
MWarehouse wh = MWarehouse.get(Env.getCtx(), receipt.getM_Warehouse_ID());
|
||||
int M_Locator_ID = wh.getDefaultLocator().getM_Locator_ID();
|
||||
receiptLine.setM_Locator_ID(M_Locator_ID);
|
||||
receiptLine.saveEx();
|
||||
|
||||
info = MWorkflow.runDocumentActionWorkflow(receipt, DocAction.ACTION_Complete);
|
||||
receipt.load(getTrxName());
|
||||
assertFalse(info.isError(), info.getSummary());
|
||||
assertEquals(DocAction.STATUS_Completed, receipt.getDocStatus());
|
||||
|
||||
if (!receipt.isPosted()) {
|
||||
String error = DocumentEngine.postImmediate(Env.getCtx(), receipt.getAD_Client_ID(), MInOut.Table_ID, receipt.get_ID(), false, getTrxName());
|
||||
assertTrue(error == null);
|
||||
}
|
||||
receipt.load(getTrxName());
|
||||
assertTrue(receipt.isPosted());
|
||||
|
||||
MInvoice invoice = new MInvoice(receipt, receipt.getMovementDate());
|
||||
invoice.setC_DocTypeTarget_ID(MDocType.DOCBASETYPE_APInvoice);
|
||||
invoice.setDocStatus(DocAction.STATUS_Drafted);
|
||||
invoice.setDocAction(DocAction.ACTION_Complete);
|
||||
invoice.saveEx();
|
||||
|
||||
MInvoiceLine invoiceLine = new MInvoiceLine(invoice);
|
||||
invoiceLine.setM_InOutLine_ID(receiptLine.get_ID());
|
||||
invoiceLine.setLine(10);
|
||||
invoiceLine.setProduct(mulch);
|
||||
invoiceLine.setQty(BigDecimal.ONE);
|
||||
invoiceLine.saveEx();
|
||||
|
||||
info = MWorkflow.runDocumentActionWorkflow(invoice, DocAction.ACTION_Complete);
|
||||
invoice.load(getTrxName());
|
||||
assertFalse(info.isError(), info.getSummary());
|
||||
assertEquals(DocAction.STATUS_Completed, invoice.getDocStatus());
|
||||
|
||||
if (!invoice.isPosted()) {
|
||||
String error = DocumentEngine.postImmediate(Env.getCtx(), invoice.getAD_Client_ID(), MInvoice.Table_ID, invoice.get_ID(), false, getTrxName());
|
||||
assertTrue(error == null);
|
||||
}
|
||||
invoice.load(getTrxName());
|
||||
assertTrue(invoice.isPosted());
|
||||
|
||||
MMatchInv[] miList = MMatchInv.getInvoiceLine(Env.getCtx(), invoiceLine.get_ID(), getTrxName());
|
||||
for (MMatchInv mi : miList) {
|
||||
if (!mi.isPosted()) {
|
||||
String error = DocumentEngine.postImmediate(Env.getCtx(), mi.getAD_Client_ID(), MMatchInv.Table_ID, mi.get_ID(), false, getTrxName());
|
||||
assertTrue(error == null);
|
||||
}
|
||||
mi.load(getTrxName());
|
||||
assertTrue(mi.isPosted());
|
||||
|
||||
Doc doc = DocManager.getDocument(as, MMatchInv.Table_ID, mi.get_ID(), getTrxName());
|
||||
doc.setC_BPartner_ID(mi.getC_InvoiceLine().getC_Invoice().getC_BPartner_ID());
|
||||
MAccount acctNIR = doc.getAccount(Doc.ACCTTYPE_NotInvoicedReceipts, as);
|
||||
|
||||
ProductCost pc = new ProductCost (Env.getCtx(), mi.getM_Product_ID(), mi.getM_AttributeSetInstance_ID(), getTrxName());
|
||||
MAccount acctInvClr = pc.getAccount(ProductCost.ACCTTYPE_P_InventoryClearing, as);
|
||||
MAccount acctIPV = pc.getAccount(ProductCost.ACCTTYPE_P_IPV, as);
|
||||
int C_AcctSchema_ID = as.getC_AcctSchema_ID();
|
||||
|
||||
String whereClause2 = MFactAcct.COLUMNNAME_AD_Table_ID + "=" + MMatchInv.Table_ID
|
||||
+ " AND " + MFactAcct.COLUMNNAME_Record_ID + "=" + mi.get_ID()
|
||||
+ " AND " + MFactAcct.COLUMNNAME_C_AcctSchema_ID + "=" + C_AcctSchema_ID;
|
||||
int[] ids = MFactAcct.getAllIDs(MFactAcct.Table_Name, whereClause2, getTrxName());
|
||||
BigDecimal invMatchAmt = invoiceLine.getMatchedQty().multiply(invoiceLine.getPriceActual()).setScale(as.getStdPrecision(), RoundingMode.HALF_UP);
|
||||
mulchCost = mulchCost.setScale(as.getStdPrecision(), RoundingMode.HALF_UP);
|
||||
for (int id : ids) {
|
||||
MFactAcct fa = new MFactAcct(Env.getCtx(), id, getTrxName());
|
||||
if (fa.getAccount_ID() == acctNIR.getAccount_ID())
|
||||
assertEquals(fa.getAmtAcctDr().setScale(2, RoundingMode.HALF_UP), mulchCost.setScale(2, RoundingMode.HALF_UP), "");
|
||||
else if (fa.getAccount_ID() == acctInvClr.getAccount_ID())
|
||||
assertEquals(fa.getAmtAcctCr().setScale(2, RoundingMode.HALF_UP), invMatchAmt.setScale(2, RoundingMode.HALF_UP), "");
|
||||
else if (fa.getAccount_ID() == acctIPV.getAccount_ID())
|
||||
assertEquals(fa.getAmtAcctDr().subtract(fa.getAmtAcctCr()).setScale(2, RoundingMode.HALF_UP), invMatchAmt.subtract(mulchCost).setScale(2, RoundingMode.HALF_UP), "");
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
getTrx().rollback();
|
||||
category.deleteEx(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
/**
|
||||
* Test the matched invoice posting for credit memo
|
||||
|
|
|
@ -0,0 +1,263 @@
|
|||
/***********************************************************************
|
||||
* This file is part of iDempiere ERP Open Source *
|
||||
* http://www.idempiere.org *
|
||||
* *
|
||||
* Copyright (C) Contributors *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software *
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
|
||||
* MA 02110-1301, USA. *
|
||||
* *
|
||||
* Contributors: *
|
||||
* - Elaine Tan - etantg *
|
||||
* - hengsin *
|
||||
**********************************************************************/
|
||||
package org.idempiere.test.base;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.List;
|
||||
|
||||
import org.compiere.acct.Doc;
|
||||
import org.compiere.acct.DocManager;
|
||||
import org.compiere.model.MAccount;
|
||||
import org.compiere.model.MAcctSchema;
|
||||
import org.compiere.model.MBPartner;
|
||||
import org.compiere.model.MClient;
|
||||
import org.compiere.model.MConversionRate;
|
||||
import org.compiere.model.MCost;
|
||||
import org.compiere.model.MDocType;
|
||||
import org.compiere.model.MFactAcct;
|
||||
import org.compiere.model.MInOut;
|
||||
import org.compiere.model.MInOutLine;
|
||||
import org.compiere.model.MInventory;
|
||||
import org.compiere.model.MInventoryLine;
|
||||
import org.compiere.model.MInvoice;
|
||||
import org.compiere.model.MInvoiceLine;
|
||||
import org.compiere.model.MMatchInv;
|
||||
import org.compiere.model.MOrder;
|
||||
import org.compiere.model.MOrderLine;
|
||||
import org.compiere.model.MProduct;
|
||||
import org.compiere.model.MProductCategory;
|
||||
import org.compiere.model.MProductCategoryAcct;
|
||||
import org.compiere.model.MWarehouse;
|
||||
import org.compiere.model.ProductCost;
|
||||
import org.compiere.model.Query;
|
||||
import org.compiere.process.DocAction;
|
||||
import org.compiere.process.DocumentEngine;
|
||||
import org.compiere.process.ProcessInfo;
|
||||
import org.compiere.util.Env;
|
||||
import org.compiere.wf.MWorkflow;
|
||||
import org.idempiere.test.AbstractTestCase;
|
||||
import org.idempiere.test.DictionaryIDs;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.parallel.Isolated;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hengsin
|
||||
*
|
||||
*/
|
||||
@Isolated
|
||||
public class MatchInvTestIsolated extends AbstractTestCase {
|
||||
|
||||
public MatchInvTestIsolated() {
|
||||
}
|
||||
|
||||
@Test
|
||||
/**
|
||||
* Test Standard Cost and Invoice Price Variance posting
|
||||
*/
|
||||
public void testMatchInvStdCost() {
|
||||
MProductCategory category = new MProductCategory(Env.getCtx(), 0, null);
|
||||
category.setName("Standard Costing");
|
||||
category.saveEx();
|
||||
String whereClause = "M_Product_Category_ID=?";
|
||||
List<MProductCategoryAcct> categoryAccts = new Query(Env.getCtx(), MProductCategoryAcct.Table_Name, whereClause, null)
|
||||
.setParameters(category.get_ID())
|
||||
.list();
|
||||
for (MProductCategoryAcct categoryAcct : categoryAccts) {
|
||||
categoryAcct.setCostingMethod(MAcctSchema.COSTINGMETHOD_StandardCosting);
|
||||
categoryAcct.saveEx();
|
||||
}
|
||||
|
||||
try {
|
||||
int mulchId = DictionaryIDs.M_Product.MULCH.id; // Mulch product
|
||||
MProduct mulch = new MProduct(Env.getCtx(), mulchId, getTrxName());
|
||||
mulch.setM_Product_Category_ID(category.get_ID());
|
||||
mulch.saveEx();
|
||||
|
||||
int purchaseId = DictionaryIDs.M_PriceList.PURCHASE.id; // Purchase Price List
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.SEED_FARM.id); // Seed Farm Inc.
|
||||
MAcctSchema as = MClient.get(getAD_Client_ID()).getAcctSchema();
|
||||
BigDecimal mulchCost = MCost.getCurrentCost(mulch, 0, getTrxName()).setScale(as.getCostingPrecision(), RoundingMode.HALF_UP);
|
||||
|
||||
// Change standard cost of mulch product to 2.1234
|
||||
int hqLocator = DictionaryIDs.M_Locator.HQ.id;
|
||||
int costAdjustmentDocTypeId = DictionaryIDs.C_DocType.COST_ADJUSTMENT.id;
|
||||
MInventory inventory = new MInventory(Env.getCtx(), 0, getTrxName());
|
||||
inventory.setCostingMethod(MAcctSchema.COSTINGMETHOD_StandardCosting);
|
||||
inventory.setC_DocType_ID(costAdjustmentDocTypeId);
|
||||
inventory.setM_Warehouse_ID(getM_Warehouse_ID());
|
||||
inventory.setMovementDate(getLoginDate());
|
||||
inventory.setDocAction(DocAction.ACTION_Complete);
|
||||
inventory.saveEx();
|
||||
|
||||
BigDecimal endProductCost = new BigDecimal("2.1234").setScale(as.getCostingPrecision(), RoundingMode.HALF_UP);
|
||||
MInventoryLine il = new MInventoryLine(Env.getCtx(), 0, getTrxName());
|
||||
il.setM_Inventory_ID(inventory.get_ID());
|
||||
il.setM_Locator_ID(hqLocator);
|
||||
il.setM_Product_ID(mulch.getM_Product_ID());
|
||||
il.setCurrentCostPrice(mulchCost);
|
||||
il.setNewCostPrice(endProductCost);
|
||||
il.saveEx();
|
||||
|
||||
ProcessInfo info = MWorkflow.runDocumentActionWorkflow(inventory, DocAction.ACTION_Complete);
|
||||
inventory.load(getTrxName());
|
||||
assertFalse(info.isError(), info.getSummary());
|
||||
assertEquals(DocAction.STATUS_Completed, inventory.getDocStatus(), "Cost Adjustment Status="+inventory.getDocStatus());
|
||||
|
||||
if (!inventory.isPosted()) {
|
||||
String msg = DocumentEngine.postImmediate(Env.getCtx(), getAD_Client_ID(), MInventory.Table_ID, inventory.get_ID(), false, getTrxName());
|
||||
assertNull(msg, msg);
|
||||
}
|
||||
mulchCost = MCost.getCurrentCost(mulch, 0, getTrxName()).setScale(as.getCostingPrecision(), RoundingMode.HALF_UP);
|
||||
assertEquals(endProductCost, mulchCost, "Cost not adjusted: " + mulchCost.toPlainString());
|
||||
|
||||
//test converted cost for all schemas
|
||||
MAcctSchema[] schemas = MAcctSchema.getClientAcctSchema(Env.getCtx(), getAD_Client_ID());
|
||||
for (int i = 0; i < schemas.length; i++) {
|
||||
BigDecimal expected = MConversionRate.convert (Env.getCtx(),
|
||||
mulchCost, as.getC_Currency_ID(), schemas[i].getC_Currency_ID(),
|
||||
inventory.getMovementDate(), 0, getAD_Client_ID(), getAD_Org_ID(), true);
|
||||
BigDecimal mulchCostConv = MCost.getCurrentCost(mulch, 0, schemas[i], schemas[i].getAD_Org_ID(), MAcctSchema.COSTINGMETHOD_StandardCosting,
|
||||
BigDecimal.ONE, 0, true, getTrxName()).setScale(schemas[i].getCostingPrecision(), RoundingMode.HALF_UP);
|
||||
assertEquals(expected, mulchCostConv, "Converted Cost for schema incorrect: " + schemas[i].toString()+ " - " + mulchCostConv.toPlainString());
|
||||
}
|
||||
|
||||
MOrder order = new MOrder(Env.getCtx(), 0, getTrxName());
|
||||
order.setBPartner(bpartner);
|
||||
order.setIsSOTrx(false);
|
||||
order.setC_DocTypeTarget_ID();
|
||||
order.setM_PriceList_ID(purchaseId);
|
||||
order.setDocStatus(DocAction.STATUS_Drafted);
|
||||
order.setDocAction(DocAction.ACTION_Complete);
|
||||
order.saveEx();
|
||||
|
||||
MOrderLine orderLine = new MOrderLine(order);
|
||||
orderLine.setLine(10);
|
||||
orderLine.setProduct(mulch);
|
||||
orderLine.setQty(BigDecimal.ONE);
|
||||
orderLine.saveEx();
|
||||
|
||||
info = MWorkflow.runDocumentActionWorkflow(order, DocAction.ACTION_Complete);
|
||||
order.load(getTrxName());
|
||||
assertFalse(info.isError(), info.getSummary());
|
||||
assertEquals(DocAction.STATUS_Completed, order.getDocStatus());
|
||||
|
||||
MInOut receipt = new MInOut(order, 122, order.getDateOrdered()); // MM Receipt
|
||||
receipt.saveEx();
|
||||
|
||||
MInOutLine receiptLine = new MInOutLine(receipt);
|
||||
receiptLine.setC_OrderLine_ID(orderLine.get_ID());
|
||||
receiptLine.setLine(10);
|
||||
receiptLine.setProduct(mulch);
|
||||
receiptLine.setQty(BigDecimal.ONE);
|
||||
MWarehouse wh = MWarehouse.get(Env.getCtx(), receipt.getM_Warehouse_ID());
|
||||
int M_Locator_ID = wh.getDefaultLocator().getM_Locator_ID();
|
||||
receiptLine.setM_Locator_ID(M_Locator_ID);
|
||||
receiptLine.saveEx();
|
||||
|
||||
info = MWorkflow.runDocumentActionWorkflow(receipt, DocAction.ACTION_Complete);
|
||||
receipt.load(getTrxName());
|
||||
assertFalse(info.isError(), info.getSummary());
|
||||
assertEquals(DocAction.STATUS_Completed, receipt.getDocStatus());
|
||||
|
||||
if (!receipt.isPosted()) {
|
||||
String error = DocumentEngine.postImmediate(Env.getCtx(), receipt.getAD_Client_ID(), MInOut.Table_ID, receipt.get_ID(), false, getTrxName());
|
||||
assertTrue(error == null);
|
||||
}
|
||||
receipt.load(getTrxName());
|
||||
assertTrue(receipt.isPosted());
|
||||
|
||||
MInvoice invoice = new MInvoice(receipt, receipt.getMovementDate());
|
||||
invoice.setC_DocTypeTarget_ID(MDocType.DOCBASETYPE_APInvoice);
|
||||
invoice.setDocStatus(DocAction.STATUS_Drafted);
|
||||
invoice.setDocAction(DocAction.ACTION_Complete);
|
||||
invoice.saveEx();
|
||||
|
||||
MInvoiceLine invoiceLine = new MInvoiceLine(invoice);
|
||||
invoiceLine.setM_InOutLine_ID(receiptLine.get_ID());
|
||||
invoiceLine.setLine(10);
|
||||
invoiceLine.setProduct(mulch);
|
||||
invoiceLine.setQty(BigDecimal.ONE);
|
||||
invoiceLine.saveEx();
|
||||
|
||||
info = MWorkflow.runDocumentActionWorkflow(invoice, DocAction.ACTION_Complete);
|
||||
invoice.load(getTrxName());
|
||||
assertFalse(info.isError(), info.getSummary());
|
||||
assertEquals(DocAction.STATUS_Completed, invoice.getDocStatus());
|
||||
|
||||
if (!invoice.isPosted()) {
|
||||
String error = DocumentEngine.postImmediate(Env.getCtx(), invoice.getAD_Client_ID(), MInvoice.Table_ID, invoice.get_ID(), false, getTrxName());
|
||||
assertTrue(error == null);
|
||||
}
|
||||
invoice.load(getTrxName());
|
||||
assertTrue(invoice.isPosted());
|
||||
|
||||
MMatchInv[] miList = MMatchInv.getInvoiceLine(Env.getCtx(), invoiceLine.get_ID(), getTrxName());
|
||||
for (MMatchInv mi : miList) {
|
||||
if (!mi.isPosted()) {
|
||||
String error = DocumentEngine.postImmediate(Env.getCtx(), mi.getAD_Client_ID(), MMatchInv.Table_ID, mi.get_ID(), false, getTrxName());
|
||||
assertTrue(error == null);
|
||||
}
|
||||
mi.load(getTrxName());
|
||||
assertTrue(mi.isPosted());
|
||||
|
||||
Doc doc = DocManager.getDocument(as, MMatchInv.Table_ID, mi.get_ID(), getTrxName());
|
||||
doc.setC_BPartner_ID(mi.getC_InvoiceLine().getC_Invoice().getC_BPartner_ID());
|
||||
MAccount acctNIR = doc.getAccount(Doc.ACCTTYPE_NotInvoicedReceipts, as);
|
||||
|
||||
ProductCost pc = new ProductCost (Env.getCtx(), mi.getM_Product_ID(), mi.getM_AttributeSetInstance_ID(), getTrxName());
|
||||
MAccount acctInvClr = pc.getAccount(ProductCost.ACCTTYPE_P_InventoryClearing, as);
|
||||
MAccount acctIPV = pc.getAccount(ProductCost.ACCTTYPE_P_IPV, as);
|
||||
int C_AcctSchema_ID = as.getC_AcctSchema_ID();
|
||||
|
||||
String whereClause2 = MFactAcct.COLUMNNAME_AD_Table_ID + "=" + MMatchInv.Table_ID
|
||||
+ " AND " + MFactAcct.COLUMNNAME_Record_ID + "=" + mi.get_ID()
|
||||
+ " AND " + MFactAcct.COLUMNNAME_C_AcctSchema_ID + "=" + C_AcctSchema_ID;
|
||||
int[] ids = MFactAcct.getAllIDs(MFactAcct.Table_Name, whereClause2, getTrxName());
|
||||
BigDecimal invMatchAmt = invoiceLine.getMatchedQty().multiply(invoiceLine.getPriceActual()).setScale(as.getStdPrecision(), RoundingMode.HALF_UP);
|
||||
mulchCost = mulchCost.setScale(as.getStdPrecision(), RoundingMode.HALF_UP);
|
||||
for (int id : ids) {
|
||||
MFactAcct fa = new MFactAcct(Env.getCtx(), id, getTrxName());
|
||||
if (fa.getAccount_ID() == acctNIR.getAccount_ID())
|
||||
assertEquals(fa.getAmtAcctDr().setScale(2, RoundingMode.HALF_UP), mulchCost.setScale(2, RoundingMode.HALF_UP), "");
|
||||
else if (fa.getAccount_ID() == acctInvClr.getAccount_ID())
|
||||
assertEquals(fa.getAmtAcctCr().setScale(2, RoundingMode.HALF_UP), invMatchAmt.setScale(2, RoundingMode.HALF_UP), "");
|
||||
else if (fa.getAccount_ID() == acctIPV.getAccount_ID())
|
||||
assertEquals(fa.getAmtAcctDr().subtract(fa.getAmtAcctCr()).setScale(2, RoundingMode.HALF_UP), invMatchAmt.subtract(mulchCost).setScale(2, RoundingMode.HALF_UP), "");
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
getTrx().rollback();
|
||||
category.deleteEx(true);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -87,7 +87,7 @@ public class CreateFromInvoiceFormTest extends AbstractTestCase {
|
|||
|
||||
MOrderLine line1 = new MOrderLine(order);
|
||||
line1.setLine(10);
|
||||
line1.setProduct(MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.MULCH.id));
|
||||
line1.setProduct(MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.HOLLY_BUSH.id));
|
||||
line1.setQty(new BigDecimal("1"));
|
||||
line1.setDatePromised(today);
|
||||
line1.saveEx();
|
||||
|
@ -179,7 +179,7 @@ public class CreateFromInvoiceFormTest extends AbstractTestCase {
|
|||
|
||||
MOrderLine line1 = new MOrderLine(order);
|
||||
line1.setLine(10);
|
||||
line1.setProduct(MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.MULCH.id));
|
||||
line1.setProduct(MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.HOLLY_BUSH.id));
|
||||
line1.setQty(new BigDecimal("1"));
|
||||
line1.setDatePromised(today);
|
||||
line1.saveEx();
|
||||
|
|
|
@ -85,7 +85,7 @@ public class CreateFromRMAFormTest extends AbstractTestCase {
|
|||
|
||||
MOrderLine orderLine = new MOrderLine(order);
|
||||
orderLine.setLine(10);
|
||||
orderLine.setProduct(MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.MULCH.id));
|
||||
orderLine.setProduct(MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.HOLLY_BUSH.id));
|
||||
orderLine.setQty(new BigDecimal("1"));
|
||||
orderLine.setDatePromised(today);
|
||||
orderLine.saveEx();
|
||||
|
|
|
@ -90,7 +90,7 @@ public class CreateFromShipmentFormTest extends AbstractTestCase {
|
|||
|
||||
MOrderLine orderLine = new MOrderLine(order);
|
||||
orderLine.setLine(10);
|
||||
orderLine.setProduct(MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.MULCH.id));
|
||||
orderLine.setProduct(MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.HOLLY_BUSH.id));
|
||||
orderLine.setQty(new BigDecimal("1"));
|
||||
orderLine.setDatePromised(today);
|
||||
orderLine.saveEx();
|
||||
|
@ -170,7 +170,7 @@ public class CreateFromShipmentFormTest extends AbstractTestCase {
|
|||
|
||||
MOrderLine orderLine = new MOrderLine(order);
|
||||
orderLine.setLine(10);
|
||||
orderLine.setProduct(MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.MULCH.id));
|
||||
orderLine.setProduct(MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.HOLLY_BUSH.id));
|
||||
orderLine.setQty(new BigDecimal("1"));
|
||||
orderLine.setDatePromised(today);
|
||||
orderLine.saveEx();
|
||||
|
|
|
@ -59,11 +59,14 @@ import org.compiere.model.Query;
|
|||
import org.compiere.process.DocAction;
|
||||
import org.compiere.process.DocumentEngine;
|
||||
import org.compiere.process.ProcessInfo;
|
||||
import org.compiere.util.DB;
|
||||
import org.compiere.util.Env;
|
||||
import org.compiere.wf.MWorkflow;
|
||||
import org.idempiere.test.AbstractTestCase;
|
||||
import org.idempiere.test.ConversionRateHelper;
|
||||
import org.idempiere.test.DictionaryIDs;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.parallel.ResourceLock;
|
||||
|
||||
/**
|
||||
* @author Elaine Tan - etantg
|
||||
|
@ -74,6 +77,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MConversionRate.Table_Name)
|
||||
/**
|
||||
* Test the allocation posting (different period)
|
||||
* Invoice Total=12,587.48, Period 1
|
||||
|
@ -179,6 +183,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MConversionRate.Table_Name)
|
||||
/**
|
||||
* Test the allocation posting (same period)
|
||||
* Invoice Total=12,587.48
|
||||
|
@ -189,7 +194,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase {
|
|||
* https://idempiere.atlassian.net/browse/IDEMPIERE-5053
|
||||
*/
|
||||
public void testAllocateInvoicePaymentPosting_2() {
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.C_AND_W.id); // C&W Construction
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.SEED_FARM.id);
|
||||
MCharge charge = MCharge.get(Env.getCtx(), DictionaryIDs.C_Charge.FREIGHT.id); // Freight Charges
|
||||
Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date");
|
||||
Timestamp date = currentDate;
|
||||
|
@ -265,6 +270,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MConversionRate.Table_Name)
|
||||
/**
|
||||
* Test the allocation posting (different period)
|
||||
* Payment Total=12,000, Period 1
|
||||
|
@ -273,7 +279,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase {
|
|||
* https://idempiere.atlassian.net/browse/IDEMPIERE-4200
|
||||
*/
|
||||
public void testAllocateInvoicePaymentPosting_3() {
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.C_AND_W.id); // C&W Construction
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.PATIO.id);
|
||||
MCharge charge = MCharge.get(Env.getCtx(), DictionaryIDs.C_Charge.FREIGHT.id); // Freight Charges
|
||||
Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date");
|
||||
Calendar cal = Calendar.getInstance();
|
||||
|
@ -336,6 +342,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MConversionRate.Table_Name)
|
||||
/**
|
||||
* Test the allocation posting (same period)
|
||||
* Payment Total=12,000
|
||||
|
@ -344,7 +351,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase {
|
|||
* https://idempiere.atlassian.net/browse/IDEMPIERE-4200
|
||||
*/
|
||||
public void testAllocateInvoicePaymentPosting_4() {
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.C_AND_W.id); // C&W Construction
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.AGRI_TECH.id);
|
||||
MCharge charge = MCharge.get(Env.getCtx(), DictionaryIDs.C_Charge.FREIGHT.id); // Freight Charges
|
||||
Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date");
|
||||
Timestamp date = currentDate;
|
||||
|
@ -396,6 +403,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MConversionRate.Table_Name)
|
||||
/**
|
||||
* Test the allocation posting (different period)
|
||||
* Invoice1 Total=9,362.50, Period 1
|
||||
|
@ -410,7 +418,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase {
|
|||
* https://idempiere.atlassian.net/browse/IDEMPIERE-4200
|
||||
*/
|
||||
public void testAllocateInvoicePaymentPosting_5() {
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.C_AND_W.id); // C&W Construction
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.JOE_BLOCK.id);
|
||||
MCharge charge = MCharge.get(Env.getCtx(), DictionaryIDs.C_Charge.FREIGHT.id); // Freight Charges
|
||||
Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date");
|
||||
Calendar cal = Calendar.getInstance();
|
||||
|
@ -545,6 +553,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MConversionRate.Table_Name)
|
||||
/**
|
||||
* Test the allocation posting (same period)
|
||||
* Invoice1 Total=9,362.50
|
||||
|
@ -682,6 +691,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MConversionRate.Table_Name)
|
||||
/**
|
||||
* Test the allocation posting (different period)
|
||||
* Payment Total=12,000, Period 1
|
||||
|
@ -692,7 +702,8 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase {
|
|||
* https://idempiere.atlassian.net/browse/IDEMPIERE-4127
|
||||
*/
|
||||
public void testAllocateInvoicePaymentPosting_7() {
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.C_AND_W.id); // C&W Construction
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.SEED_FARM.id, getTrxName());
|
||||
DB.getDatabase().forUpdate(bpartner, 0);
|
||||
MCharge charge = MCharge.get(Env.getCtx(), DictionaryIDs.C_Charge.FREIGHT.id); // Freight Charges
|
||||
Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date");
|
||||
Calendar cal = Calendar.getInstance();
|
||||
|
@ -783,6 +794,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MConversionRate.Table_Name)
|
||||
/**
|
||||
* Test the allocation posting (same period)
|
||||
* Payment Total=12,000
|
||||
|
@ -793,7 +805,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase {
|
|||
* https://idempiere.atlassian.net/browse/IDEMPIERE-4127
|
||||
*/
|
||||
public void testAllocateInvoicePaymentPosting_8() {
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.C_AND_W.id); // C&W Construction
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.PATIO.id, getTrxName()); // C&W Construction
|
||||
MCharge charge = MCharge.get(Env.getCtx(), DictionaryIDs.C_Charge.FREIGHT.id); // Freight Charges
|
||||
Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date");
|
||||
Timestamp date = currentDate;
|
||||
|
@ -810,6 +822,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase {
|
|||
try {
|
||||
MBankAccount ba = getBankAccount(usd.getC_Currency_ID());
|
||||
BigDecimal payAmt = new BigDecimal(12000);
|
||||
DB.getDatabase().forUpdate(bpartner, 0);
|
||||
MPayment payment = createPayment(true, bpartner, ba.getC_BankAccount_ID(), date, payAmt, euro.getC_Currency_ID(), C_ConversionType_ID);
|
||||
completeDocument(payment);
|
||||
postDocument(payment);
|
||||
|
@ -873,6 +886,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MConversionRate.Table_Name)
|
||||
/**
|
||||
* Test the allocation posting (different period)
|
||||
* Invoice Total=12,000, Period 1
|
||||
|
@ -883,7 +897,9 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase {
|
|||
* https://idempiere.atlassian.net/browse/IDEMPIERE-4127
|
||||
*/
|
||||
public void testAllocateInvoicePaymentPosting_9() {
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.C_AND_W.id); // C&W Construction
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.AGRI_TECH.id, getTrxName());
|
||||
DB.getDatabase().forUpdate(bpartner, 0);
|
||||
|
||||
MCharge charge = MCharge.get(Env.getCtx(), DictionaryIDs.C_Charge.FREIGHT.id); // Freight Charges
|
||||
Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date");
|
||||
Calendar cal = Calendar.getInstance();
|
||||
|
@ -972,6 +988,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MConversionRate.Table_Name)
|
||||
/**
|
||||
* Test the allocation posting (same period)
|
||||
* Invoice Total=12,000
|
||||
|
@ -982,7 +999,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase {
|
|||
* https://idempiere.atlassian.net/browse/IDEMPIERE-4127
|
||||
*/
|
||||
public void testAllocateInvoicePaymentPosting_10() {
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.C_AND_W.id); // C&W Construction
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.JOE_BLOCK.id);
|
||||
MCharge charge = MCharge.get(Env.getCtx(), DictionaryIDs.C_Charge.FREIGHT.id); // Freight Charges
|
||||
Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date");
|
||||
Timestamp date = currentDate;
|
||||
|
@ -1060,6 +1077,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MConversionRate.Table_Name)
|
||||
/**
|
||||
* Test the allocation posting (different period + reversal)
|
||||
* Invoice Total=1000, Period 1
|
||||
|
@ -1223,6 +1241,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MConversionRate.Table_Name)
|
||||
/**
|
||||
* Test the allocation posting (different period + reversal)
|
||||
* Payment Total=1000, Period 1
|
||||
|
@ -1231,7 +1250,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase {
|
|||
* https://idempiere.atlassian.net/browse/IDEMPIERE-5339
|
||||
*/
|
||||
public void testAllocateInvoicePaymentPosting_12() {
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.C_AND_W.id); // C&W Construction
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.SEED_FARM.id);
|
||||
MCharge charge = MCharge.get(Env.getCtx(), DictionaryIDs.C_Charge.FREIGHT.id); // Freight Charges
|
||||
Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date");
|
||||
|
||||
|
@ -1386,6 +1405,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MConversionRate.Table_Name)
|
||||
/**
|
||||
* Test the allocation posting (different period + reversal)
|
||||
* Invoice Total=1000, Period 1
|
||||
|
@ -1449,6 +1469,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MConversionRate.Table_Name)
|
||||
/**
|
||||
* Test the allocation posting (same period + reversal)
|
||||
* Invoice Total=1000
|
||||
|
@ -1456,7 +1477,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase {
|
|||
* https://idempiere.atlassian.net/browse/IDEMPIERE-4696
|
||||
*/
|
||||
public void testAllocateInvoicePosting_2() {
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.TREE_FARM.id); // Tree Farm Inc.
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.C_AND_W.id);
|
||||
MCharge charge = MCharge.get(Env.getCtx(), DictionaryIDs.C_Charge.FREIGHT.id); // Freight Charges
|
||||
Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date");
|
||||
Timestamp date = currentDate;
|
||||
|
@ -1500,6 +1521,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MConversionRate.Table_Name)
|
||||
/**
|
||||
* Test the allocation posting (different period + offset)
|
||||
* Invoice Total=1000, Period 1
|
||||
|
@ -1507,7 +1529,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase {
|
|||
* https://idempiere.atlassian.net/browse/IDEMPIERE-4696
|
||||
*/
|
||||
public void testAllocateInvoicePosting_3() {
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.TREE_FARM.id); // Tree Farm Inc.
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.SEED_FARM.id);
|
||||
MCharge charge = MCharge.get(Env.getCtx(), DictionaryIDs.C_Charge.FREIGHT.id); // Freight Charges
|
||||
Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date");
|
||||
|
||||
|
@ -1572,6 +1594,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MConversionRate.Table_Name)
|
||||
/**
|
||||
* Test the allocation posting (same period + offset)
|
||||
* Invoice Total=1000
|
||||
|
@ -1579,7 +1602,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase {
|
|||
* https://idempiere.atlassian.net/browse/IDEMPIERE-4696
|
||||
*/
|
||||
public void testAllocateInvoicePosting_4() {
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.TREE_FARM.id); // Tree Farm Inc.
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.PATIO.id);
|
||||
MCharge charge = MCharge.get(Env.getCtx(), DictionaryIDs.C_Charge.FREIGHT.id); // Freight Charges
|
||||
Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date");
|
||||
Timestamp date = currentDate;
|
||||
|
@ -1632,6 +1655,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MConversionRate.Table_Name)
|
||||
/**
|
||||
* Test the allocation posting (different period + reversal)
|
||||
* Payment Total=1000, Period 1
|
||||
|
@ -1639,7 +1663,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase {
|
|||
* https://idempiere.atlassian.net/browse/IDEMPIERE-4696
|
||||
*/
|
||||
public void testAllocatePaymentPosting_1() {
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.TREE_FARM.id); // Tree Farm Inc.
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.AGRI_TECH.id);
|
||||
Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date");
|
||||
|
||||
Calendar cal = Calendar.getInstance();
|
||||
|
@ -1691,6 +1715,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MConversionRate.Table_Name)
|
||||
/**
|
||||
* Test the allocation posting (same period + reversal)
|
||||
* Payment Total=1000, Period 1
|
||||
|
@ -1738,6 +1763,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MConversionRate.Table_Name)
|
||||
/**
|
||||
* Test the allocation posting (different period + offset)
|
||||
* Payment Total=1000, Period 1
|
||||
|
@ -1745,7 +1771,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase {
|
|||
* https://idempiere.atlassian.net/browse/IDEMPIERE-4696
|
||||
*/
|
||||
public void testAllocatePaymentPosting_3() {
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.TREE_FARM.id); // Tree Farm Inc.
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.C_AND_W.id);
|
||||
Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date");
|
||||
|
||||
Calendar cal = Calendar.getInstance();
|
||||
|
@ -1803,6 +1829,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MConversionRate.Table_Name)
|
||||
/**
|
||||
* Test the allocation posting (same period + offset)
|
||||
* Payment Total=1000
|
||||
|
@ -1862,34 +1889,11 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase {
|
|||
|
||||
private MConversionRate createConversionRate(int C_Currency_ID, int C_Currency_ID_To, int C_ConversionType_ID,
|
||||
Timestamp date, BigDecimal rate, boolean isMultiplyRate) {
|
||||
MConversionRate cr = new MConversionRate(Env.getCtx(), 0, null);
|
||||
cr.setC_Currency_ID(C_Currency_ID);
|
||||
cr.setC_Currency_ID_To(C_Currency_ID_To);
|
||||
cr.setC_ConversionType_ID(C_ConversionType_ID);
|
||||
cr.setValidFrom(date);
|
||||
cr.setValidTo(date);
|
||||
if (isMultiplyRate)
|
||||
cr.setMultiplyRate(rate);
|
||||
else
|
||||
cr.setDivideRate(rate);
|
||||
cr.saveEx();
|
||||
return cr;
|
||||
return ConversionRateHelper.createConversionRate(C_Currency_ID, C_Currency_ID_To, C_ConversionType_ID, date, rate, isMultiplyRate);
|
||||
}
|
||||
|
||||
private void deleteConversionRate(MConversionRate cr) {
|
||||
String whereClause = "ValidFrom=? AND ValidTo=? "
|
||||
+ "AND C_Currency_ID=? AND C_Currency_ID_To=? "
|
||||
+ "AND C_ConversionType_ID=? "
|
||||
+ "AND AD_Client_ID=? AND AD_Org_ID=?";
|
||||
MConversionRate reciprocal = new Query(Env.getCtx(), MConversionRate.Table_Name, whereClause, null)
|
||||
.setParameters(cr.getValidFrom(), cr.getValidTo(),
|
||||
cr.getC_Currency_ID_To(), cr.getC_Currency_ID(),
|
||||
cr.getC_ConversionType_ID(),
|
||||
cr.getAD_Client_ID(), cr.getAD_Org_ID())
|
||||
.firstOnly();
|
||||
if (reciprocal != null)
|
||||
reciprocal.deleteEx(true);
|
||||
cr.deleteEx(true);
|
||||
ConversionRateHelper.deleteConversionRate(cr);
|
||||
}
|
||||
|
||||
private MInvoice createInvoice(boolean isSOTrx, MBPartner bpartner, Timestamp date, int M_PriceList_ID, int C_ConversionType_ID) {
|
||||
|
|
|
@ -56,17 +56,22 @@ import org.compiere.process.DocAction;
|
|||
import org.compiere.process.DocumentEngine;
|
||||
import org.compiere.process.ProcessInfo;
|
||||
import org.compiere.util.CLogErrorBuffer;
|
||||
import org.compiere.util.DB;
|
||||
import org.compiere.util.Env;
|
||||
import org.compiere.util.TimeUtil;
|
||||
import org.compiere.wf.MWorkflow;
|
||||
import org.idempiere.test.AbstractTestCase;
|
||||
import org.idempiere.test.ConversionRateHelper;
|
||||
import org.idempiere.test.DictionaryIDs;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.parallel.Isolated;
|
||||
import org.junit.jupiter.api.parallel.ResourceLock;
|
||||
|
||||
/**
|
||||
* @author Carlos Ruiz - globalqss
|
||||
*
|
||||
*/
|
||||
@Isolated
|
||||
public class AllocationTest extends AbstractTestCase {
|
||||
|
||||
/**
|
||||
|
@ -176,12 +181,13 @@ public class AllocationTest extends AbstractTestCase {
|
|||
String trxName = getTrxName();
|
||||
|
||||
// Get the OpenBalance of C&W
|
||||
MBPartner bpartner = new MBPartner(ctx, DictionaryIDs.C_BPartner.C_AND_W.id, trxName);
|
||||
MBPartner bpartner = new MBPartner(ctx, DictionaryIDs.C_BPartner.PATIO.id, trxName);
|
||||
DB.getDatabase().forUpdate(bpartner, 0);
|
||||
BigDecimal initialBalance = bpartner.getTotalOpenBalance();
|
||||
|
||||
// Create Invoice $100
|
||||
MInvoice invoice = new MInvoice(ctx, 0, trxName);
|
||||
invoice.setBPartner(MBPartner.get(ctx, DictionaryIDs.C_BPartner.C_AND_W.id));
|
||||
invoice.setBPartner(MBPartner.get(ctx, DictionaryIDs.C_BPartner.PATIO.id));
|
||||
invoice.setC_DocTypeTarget_ID(MDocType.DOCBASETYPE_ARInvoice);
|
||||
invoice.setC_DocType_ID(invoice.getC_DocTypeTarget_ID()); // required to avoid runDocumentActionWorkflow exception
|
||||
invoice.setPaymentRule(MInvoice.PAYMENTRULE_Check);
|
||||
|
@ -340,11 +346,12 @@ public class AllocationTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MConversionRate.Table_Name)
|
||||
/**
|
||||
* https://idempiere.atlassian.net/browse/IDEMPIERE-4696
|
||||
*/
|
||||
public void testPaymentReversePosting() {
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), 114); // Tree Farm Inc.
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.COLOR_INC.id);
|
||||
Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date");
|
||||
|
||||
Calendar cal = Calendar.getInstance();
|
||||
|
@ -427,8 +434,9 @@ public class AllocationTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MConversionRate.Table_Name)
|
||||
public void testAllocatePaymentPosting() {
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), 114); // Tree Farm Inc.
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.CHROME_INC.id);
|
||||
Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date");
|
||||
|
||||
Calendar cal = Calendar.getInstance();
|
||||
|
@ -532,34 +540,11 @@ public class AllocationTest extends AbstractTestCase {
|
|||
|
||||
private MConversionRate createConversionRate(int C_Currency_ID, int C_Currency_ID_To, int C_ConversionType_ID,
|
||||
Timestamp date, BigDecimal rate, boolean isMultiplyRate) {
|
||||
MConversionRate cr = new MConversionRate(Env.getCtx(), 0, null);
|
||||
cr.setC_Currency_ID(C_Currency_ID);
|
||||
cr.setC_Currency_ID_To(C_Currency_ID_To);
|
||||
cr.setC_ConversionType_ID(C_ConversionType_ID);
|
||||
cr.setValidFrom(date);
|
||||
cr.setValidTo(date);
|
||||
if (isMultiplyRate)
|
||||
cr.setMultiplyRate(rate);
|
||||
else
|
||||
cr.setDivideRate(rate);
|
||||
cr.saveEx();
|
||||
return cr;
|
||||
return ConversionRateHelper.createConversionRate(C_Currency_ID, C_Currency_ID_To, C_ConversionType_ID, date, rate, isMultiplyRate);
|
||||
}
|
||||
|
||||
private void deleteConversionRate(MConversionRate cr) {
|
||||
String whereClause = "ValidFrom=? AND ValidTo=? "
|
||||
+ "AND C_Currency_ID=? AND C_Currency_ID_To=? "
|
||||
+ "AND C_ConversionType_ID=? "
|
||||
+ "AND AD_Client_ID=? AND AD_Org_ID=?";
|
||||
MConversionRate reciprocal = new Query(Env.getCtx(), MConversionRate.Table_Name, whereClause, null)
|
||||
.setParameters(cr.getValidFrom(), cr.getValidTo(),
|
||||
cr.getC_Currency_ID_To(), cr.getC_Currency_ID(),
|
||||
cr.getC_ConversionType_ID(),
|
||||
cr.getAD_Client_ID(), cr.getAD_Org_ID())
|
||||
.firstOnly();
|
||||
if (reciprocal != null)
|
||||
reciprocal.deleteEx(true);
|
||||
cr.deleteEx(true);
|
||||
ConversionRateHelper.deleteConversionRate(cr);
|
||||
}
|
||||
|
||||
private MPayment createReceiptPayment(int C_BPartner_ID, int C_BankAccount_ID, Timestamp date, int C_Currency_ID, int C_ConversionType_ID, BigDecimal payAmt) {
|
||||
|
@ -893,7 +878,7 @@ public class AllocationTest extends AbstractTestCase {
|
|||
// #4 check accounts
|
||||
public void testAllocatePaymentPostingWithWriteOffandDiscountAPInv() {
|
||||
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), 121); // Patio
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.PATIO.id); // Patio
|
||||
Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date");
|
||||
|
||||
Calendar cal = Calendar.getInstance();
|
||||
|
@ -1023,7 +1008,7 @@ public class AllocationTest extends AbstractTestCase {
|
|||
// #4 check accounts
|
||||
public void testAllocatePaymentPostingWithWriteOffandDiscountAPCrMe() {
|
||||
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), 121); // Patio
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.PATIO.id); // Patio
|
||||
Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date");
|
||||
|
||||
Calendar cal = Calendar.getInstance();
|
||||
|
@ -1416,7 +1401,7 @@ public class AllocationTest extends AbstractTestCase {
|
|||
// #4 check accounts
|
||||
public void testPaymentPostingWithWriteOffandDiscountAPInv() {
|
||||
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), 121); // Patio
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.AGRI_TECH.id);
|
||||
Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date");
|
||||
|
||||
Calendar cal = Calendar.getInstance();
|
||||
|
@ -1547,7 +1532,7 @@ public class AllocationTest extends AbstractTestCase {
|
|||
// #4 check accounts
|
||||
public void testPaymentPostingWithWriteOffandDiscountAPCrMe() {
|
||||
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), 121); // Patio
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.SEED_FARM.id);
|
||||
Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date");
|
||||
|
||||
Calendar cal = Calendar.getInstance();
|
||||
|
@ -1678,7 +1663,7 @@ public class AllocationTest extends AbstractTestCase {
|
|||
// #4 Check accounts
|
||||
public void testAllocatePostingWithWriteOffandDiscountARInvARCrMe() {
|
||||
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.JOE_BLOCK.id);
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.SEED_FARM.id);
|
||||
Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date");
|
||||
|
||||
Calendar cal = Calendar.getInstance();
|
||||
|
@ -1815,7 +1800,7 @@ public class AllocationTest extends AbstractTestCase {
|
|||
// #4 Check accounts
|
||||
public void testAllocatePostingWithWriteOffandDiscountAPInvAPCrMe() {
|
||||
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), 121); // Patio
|
||||
MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.SEED_FARM.id);
|
||||
Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date");
|
||||
|
||||
Calendar cal = Calendar.getInstance();
|
||||
|
@ -1943,6 +1928,7 @@ public class AllocationTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MConversionRate.Table_Name)
|
||||
/**
|
||||
* Test the allocation posting (different period)
|
||||
* Invoice Total=12,587.48, Period 1
|
||||
|
@ -1968,6 +1954,10 @@ public class AllocationTest extends AbstractTestCase {
|
|||
MCurrency usd = MCurrency.get(DictionaryIDs.C_Currency.USD.id); // USD
|
||||
MCurrency euro = MCurrency.get(DictionaryIDs.C_Currency.EUR.id); // EUR
|
||||
BigDecimal eurToUsd1 = new BigDecimal(32.458922422202);
|
||||
|
||||
MBPartner bp = new MBPartner (Env.getCtx(), DictionaryIDs.C_BPartner.C_AND_W.id, getTrxName());
|
||||
DB.getDatabase().forUpdate(bp, 0);
|
||||
|
||||
MConversionRate cr1 = createConversionRate(euro.getC_Currency_ID(), usd.getC_Currency_ID(), C_ConversionType_ID, date1, eurToUsd1, false);
|
||||
|
||||
BigDecimal eurToUsd2 = new BigDecimal(33.93972535567);
|
||||
|
|
|
@ -31,6 +31,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
|||
import java.math.BigDecimal;
|
||||
import java.sql.Timestamp;
|
||||
|
||||
import org.compiere.model.MBPartner;
|
||||
import org.compiere.model.MBankStatement;
|
||||
import org.compiere.model.MBankStatementLine;
|
||||
import org.compiere.model.MPayment;
|
||||
|
@ -40,6 +41,7 @@ import org.compiere.model.Query;
|
|||
import org.compiere.process.DocAction;
|
||||
import org.compiere.process.ProcessInfo;
|
||||
import org.compiere.util.CacheMgt;
|
||||
import org.compiere.util.DB;
|
||||
import org.compiere.util.Env;
|
||||
import org.compiere.util.Msg;
|
||||
import org.compiere.util.TimeUtil;
|
||||
|
@ -47,6 +49,7 @@ import org.compiere.wf.MWorkflow;
|
|||
import org.idempiere.test.AbstractTestCase;
|
||||
import org.idempiere.test.DictionaryIDs;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.parallel.ResourceLock;
|
||||
|
||||
/**
|
||||
* @author hengsin
|
||||
|
@ -88,6 +91,7 @@ public class BankStatementTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MSysConfig.ALLOW_REVERSAL_OF_RECONCILED_PAYMENT)
|
||||
public void testReversalOfReconciledPayment1() {
|
||||
Timestamp today = TimeUtil.getDay(System.currentTimeMillis());
|
||||
|
||||
|
@ -107,6 +111,9 @@ public class BankStatementTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
try {
|
||||
MBPartner bp = new MBPartner (Env.getCtx(), DictionaryIDs.C_BPartner.C_AND_W.id, getTrxName());
|
||||
DB.getDatabase().forUpdate(bp, 0);
|
||||
|
||||
MPayment payment1 = new MPayment(Env.getCtx(), 0, getTrxName());
|
||||
payment1.setC_BPartner_ID(DictionaryIDs.C_BPartner.C_AND_W.id); //C&W
|
||||
payment1.setC_DocType_ID(true); // Receipt
|
||||
|
@ -169,6 +176,7 @@ public class BankStatementTest extends AbstractTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = MSysConfig.ALLOW_REVERSAL_OF_RECONCILED_PAYMENT)
|
||||
public void testReversalOfReconciledPayment2() {
|
||||
Timestamp today = TimeUtil.getDay(System.currentTimeMillis());
|
||||
|
||||
|
@ -187,6 +195,9 @@ public class BankStatementTest extends AbstractTestCase {
|
|||
sysConfig = null;
|
||||
}
|
||||
try {
|
||||
MBPartner bp = new MBPartner (Env.getCtx(), DictionaryIDs.C_BPartner.C_AND_W.id, getTrxName());
|
||||
DB.getDatabase().forUpdate(bp, 0);
|
||||
|
||||
MPayment payment1 = new MPayment(Env.getCtx(), 0, getTrxName());
|
||||
payment1.setC_BPartner_ID(DictionaryIDs.C_BPartner.C_AND_W.id); //C&W
|
||||
payment1.setC_DocType_ID(true); // Receipt
|
||||
|
|
|
@ -29,15 +29,12 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
|
|||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.Arrays;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.compiere.model.MAcctSchema;
|
||||
import org.compiere.model.MAttributeSet;
|
||||
import org.compiere.model.MAttributeSetInstance;
|
||||
import org.compiere.model.MBPartner;
|
||||
import org.compiere.model.MClient;
|
||||
|
@ -48,16 +45,10 @@ import org.compiere.model.MInventory;
|
|||
import org.compiere.model.MInventoryLine;
|
||||
import org.compiere.model.MOrder;
|
||||
import org.compiere.model.MOrderLine;
|
||||
import org.compiere.model.MPriceList;
|
||||
import org.compiere.model.MPriceListVersion;
|
||||
import org.compiere.model.MProduct;
|
||||
import org.compiere.model.MProductPrice;
|
||||
import org.compiere.model.MStorageOnHand;
|
||||
import org.compiere.model.MWarehouse;
|
||||
import org.compiere.process.DocAction;
|
||||
import org.compiere.process.DocumentEngine;
|
||||
import org.compiere.process.ProcessInfo;
|
||||
import org.compiere.util.CacheMgt;
|
||||
import org.compiere.util.Env;
|
||||
import org.compiere.util.TimeUtil;
|
||||
import org.compiere.wf.MWorkflow;
|
||||
|
@ -189,194 +180,4 @@ public class InventoryTest extends AbstractTestCase {
|
|||
assertNull(error, error);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSkipProductWithSerial() {
|
||||
Properties ctx = Env.getCtx();
|
||||
String trxName = getTrxName();
|
||||
|
||||
MAttributeSet set = new MAttributeSet(Env.getCtx(), DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id, null);
|
||||
set.setIsSerNo(true);
|
||||
set.saveEx();
|
||||
|
||||
MWarehouse wh = new MWarehouse(Env.getCtx(), DictionaryIDs.M_Warehouse.HQ.id, null);
|
||||
boolean disallow = wh.isDisallowNegativeInv();
|
||||
MProduct product = null;
|
||||
try {
|
||||
|
||||
if (!disallow) {
|
||||
wh.setIsDisallowNegativeInv(true);
|
||||
wh.saveEx();
|
||||
CacheMgt.get().reset(MWarehouse.Table_Name, wh.get_ID());
|
||||
}
|
||||
|
||||
product = new MProduct(ctx, 0, null);
|
||||
product.setM_Product_Category_ID(DictionaryIDs.M_Product_Category.CHEMICALS.id);
|
||||
product.setName("testSkipProductWithSerial");
|
||||
product.setValue("testSkipProductWithSerial");
|
||||
product.setProductType(MProduct.PRODUCTTYPE_Item);
|
||||
product.setIsStocked(true);
|
||||
product.setIsSold(true);
|
||||
product.setIsPurchased(true);
|
||||
product.setC_UOM_ID(DictionaryIDs.C_UOM.EACH.id);
|
||||
product.setC_TaxCategory_ID(DictionaryIDs.C_TaxCategory.STANDARD.id);
|
||||
product.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id);
|
||||
product.saveEx();
|
||||
|
||||
MPriceListVersion plv = MPriceList.get(DictionaryIDs.M_PriceList.PURCHASE.id).getPriceListVersion(null);
|
||||
MProductPrice pp = new MProductPrice(Env.getCtx(), 0, getTrxName());
|
||||
pp.setM_PriceList_Version_ID(plv.getM_PriceList_Version_ID());
|
||||
pp.setM_Product_ID(product.get_ID());
|
||||
pp.setPriceStd(new BigDecimal("2"));
|
||||
pp.setPriceList(new BigDecimal("2"));
|
||||
pp.saveEx();
|
||||
|
||||
MAttributeSetInstance asi = new MAttributeSetInstance(Env.getCtx(), 0, getTrxName());
|
||||
asi.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id);
|
||||
asi.setSerNo("testSkipProductWithSerial #1");
|
||||
asi.saveEx();
|
||||
|
||||
createPOAndMRForProduct(product.get_ID(), asi);
|
||||
|
||||
MStorageOnHand[] onhands = MStorageOnHand.getOfProduct(Env.getCtx(), product.get_ID(), getTrxName());
|
||||
assertEquals(1, onhands.length, "Unexpected number of on hand records");
|
||||
assertEquals(onhands[0].getM_AttributeSetInstance_ID(), asi.get_ID(), "Unexpected M_AttributeSetInstance_ID for on hand record");
|
||||
|
||||
MInventory inventory = new MInventory(ctx, 0, trxName);
|
||||
inventory.setM_Warehouse_ID(DictionaryIDs.M_Warehouse.HQ.id);
|
||||
inventory.setC_DocType_ID(DictionaryIDs.C_DocType.MATERIAL_PHYSICAL_INVENTORY.id);
|
||||
inventory.saveEx();
|
||||
|
||||
MInventoryLine iline = new MInventoryLine(inventory,
|
||||
DictionaryIDs.M_Locator.HQ.id,
|
||||
product.getM_Product_ID(),
|
||||
0, // M_AttributeSetInstance_ID
|
||||
Env.ONE, // QtyBook
|
||||
Env.ZERO);
|
||||
iline.saveEx();
|
||||
|
||||
//should error out with negative on hand (skip the only asi record with serno)
|
||||
ProcessInfo info = MWorkflow.runDocumentActionWorkflow(inventory, DocAction.ACTION_Complete);
|
||||
assertTrue(info.isError(), info.getSummary());
|
||||
} finally {
|
||||
rollback();
|
||||
set.setIsSerNo(false);
|
||||
set.saveEx();
|
||||
|
||||
if (product != null)
|
||||
product.deleteEx(true);
|
||||
|
||||
if (!disallow) {
|
||||
wh.setIsDisallowNegativeInv(false);
|
||||
wh.saveEx();
|
||||
CacheMgt.get().reset(MWarehouse.Table_Name, wh.get_ID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSkipProductWithSerial2() {
|
||||
Properties ctx = Env.getCtx();
|
||||
String trxName = getTrxName();
|
||||
|
||||
MAttributeSet set = new MAttributeSet(Env.getCtx(), DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id, null);
|
||||
set.setIsSerNo(true);
|
||||
set.saveEx();
|
||||
|
||||
MWarehouse wh = new MWarehouse(Env.getCtx(), DictionaryIDs.M_Warehouse.HQ.id, null);
|
||||
boolean disallow = wh.isDisallowNegativeInv();
|
||||
MProduct product = null;
|
||||
try {
|
||||
|
||||
if (!disallow) {
|
||||
wh.setIsDisallowNegativeInv(true);
|
||||
wh.saveEx();
|
||||
CacheMgt.get().reset(MWarehouse.Table_Name, wh.get_ID());
|
||||
}
|
||||
|
||||
product = new MProduct(ctx, 0, null);
|
||||
product.setM_Product_Category_ID(DictionaryIDs.M_Product_Category.CHEMICALS.id);
|
||||
product.setName("testSkipProductWithSerial");
|
||||
product.setValue("testSkipProductWithSerial");
|
||||
product.setProductType(MProduct.PRODUCTTYPE_Item);
|
||||
product.setIsStocked(true);
|
||||
product.setIsSold(true);
|
||||
product.setIsPurchased(true);
|
||||
product.setC_UOM_ID(DictionaryIDs.C_UOM.EACH.id);
|
||||
product.setC_TaxCategory_ID(DictionaryIDs.C_TaxCategory.STANDARD.id);
|
||||
product.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id);
|
||||
product.saveEx();
|
||||
|
||||
MPriceListVersion plv = MPriceList.get(DictionaryIDs.M_PriceList.PURCHASE.id).getPriceListVersion(null);
|
||||
MProductPrice pp = new MProductPrice(Env.getCtx(), 0, getTrxName());
|
||||
pp.setM_PriceList_Version_ID(plv.getM_PriceList_Version_ID());
|
||||
pp.setM_Product_ID(product.get_ID());
|
||||
pp.setPriceStd(new BigDecimal("2"));
|
||||
pp.setPriceList(new BigDecimal("2"));
|
||||
pp.saveEx();
|
||||
|
||||
MAttributeSetInstance asi = new MAttributeSetInstance(Env.getCtx(), 0, getTrxName());
|
||||
asi.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id);
|
||||
asi.setSerNo("testSkipProductWithSerial #1");
|
||||
asi.saveEx();
|
||||
|
||||
createPOAndMRForProduct(product.get_ID(), asi);
|
||||
|
||||
MStorageOnHand[] onhands = MStorageOnHand.getOfProduct(Env.getCtx(), product.get_ID(), getTrxName());
|
||||
assertEquals(1, onhands.length, "Unexpected number of on hand records");
|
||||
assertEquals(onhands[0].getM_AttributeSetInstance_ID(), asi.get_ID(), "Unexpected M_AttributeSetInstance_ID for on hand record");
|
||||
|
||||
MAttributeSetInstance asi1 = new MAttributeSetInstance(Env.getCtx(), 0, getTrxName());
|
||||
asi1.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id);
|
||||
asi1.saveEx();
|
||||
|
||||
createPOAndMRForProduct(product.get_ID(), asi1);
|
||||
|
||||
onhands = MStorageOnHand.getOfProduct(Env.getCtx(), product.get_ID(), getTrxName());
|
||||
assertEquals(2, onhands.length, "Unexpected number of on hand records");
|
||||
Arrays.sort(onhands, new MStorageOnHand(Env.getCtx(), 0, null));
|
||||
assertEquals(onhands[0].getM_AttributeSetInstance_ID(), asi.get_ID(), "Unexpected M_AttributeSetInstance_ID for first on hand record");
|
||||
assertEquals(onhands[1].getM_AttributeSetInstance_ID(), asi1.get_ID(), "Unexpected M_AttributeSetInstance_ID for second on hand record");
|
||||
|
||||
MInventory inventory = new MInventory(ctx, 0, trxName);
|
||||
inventory.setM_Warehouse_ID(DictionaryIDs.M_Warehouse.HQ.id);
|
||||
inventory.setC_DocType_ID(DictionaryIDs.C_DocType.MATERIAL_PHYSICAL_INVENTORY.id);
|
||||
inventory.saveEx();
|
||||
|
||||
MInventoryLine iline = new MInventoryLine(inventory,
|
||||
DictionaryIDs.M_Locator.HQ.id,
|
||||
product.getM_Product_ID(),
|
||||
0, // M_AttributeSetInstance_ID
|
||||
new BigDecimal("2"), // QtyBook
|
||||
new BigDecimal("1"));
|
||||
iline.saveEx();
|
||||
|
||||
//should success with qty difference being applied to the asi with null serno record
|
||||
ProcessInfo info = MWorkflow.runDocumentActionWorkflow(inventory, DocAction.ACTION_Complete);
|
||||
assertFalse(info.isError(), info.getSummary());
|
||||
inventory.load(getTrxName());
|
||||
assertEquals(DocAction.STATUS_Completed, inventory.getDocStatus());
|
||||
|
||||
onhands = MStorageOnHand.getOfProduct(Env.getCtx(), product.get_ID(), getTrxName());
|
||||
assertEquals(2, onhands.length, "Unexpected number of on hand records");
|
||||
Arrays.sort(onhands, new MStorageOnHand(Env.getCtx(), 0, null));
|
||||
assertEquals(onhands[0].getM_AttributeSetInstance_ID(), asi.get_ID(), "Unexpected M_AttributeSetInstance_ID for first on hand record");
|
||||
assertEquals(onhands[1].getM_AttributeSetInstance_ID(), asi1.get_ID(), "Unexpected M_AttributeSetInstance_ID for second on hand record");
|
||||
assertEquals(1, onhands[0].getQtyOnHand().intValue());
|
||||
assertEquals(0, onhands[1].getQtyOnHand().intValue());
|
||||
} finally {
|
||||
rollback();
|
||||
set.setIsSerNo(false);
|
||||
set.saveEx();
|
||||
|
||||
if (product != null)
|
||||
product.deleteEx(true);
|
||||
|
||||
if (!disallow) {
|
||||
wh.setIsDisallowNegativeInv(false);
|
||||
wh.saveEx();
|
||||
CacheMgt.get().reset(MWarehouse.Table_Name, wh.get_ID());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,298 @@
|
|||
/***********************************************************************
|
||||
* This file is part of iDempiere ERP Open Source *
|
||||
* http://www.idempiere.org *
|
||||
* *
|
||||
* Copyright (C) Contributors *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software *
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
|
||||
* MA 02110-1301, USA. *
|
||||
* *
|
||||
* Contributors: *
|
||||
* - Carlos Ruiz - globalqss *
|
||||
**********************************************************************/
|
||||
package org.idempiere.test.model;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.Arrays;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.compiere.model.MAttributeSetInstance;
|
||||
import org.compiere.model.MBPartner;
|
||||
import org.compiere.model.MInOut;
|
||||
import org.compiere.model.MInOutLine;
|
||||
import org.compiere.model.MInventory;
|
||||
import org.compiere.model.MInventoryLine;
|
||||
import org.compiere.model.MOrder;
|
||||
import org.compiere.model.MOrderLine;
|
||||
import org.compiere.model.MPriceList;
|
||||
import org.compiere.model.MPriceListVersion;
|
||||
import org.compiere.model.MProduct;
|
||||
import org.compiere.model.MProductPrice;
|
||||
import org.compiere.model.MStorageOnHand;
|
||||
import org.compiere.model.MWarehouse;
|
||||
import org.compiere.process.DocAction;
|
||||
import org.compiere.process.DocumentEngine;
|
||||
import org.compiere.process.ProcessInfo;
|
||||
import org.compiere.util.CacheMgt;
|
||||
import org.compiere.util.Env;
|
||||
import org.compiere.util.TimeUtil;
|
||||
import org.compiere.wf.MWorkflow;
|
||||
import org.idempiere.test.AbstractTestCase;
|
||||
import org.idempiere.test.DictionaryIDs;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.parallel.Isolated;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hengsin
|
||||
*
|
||||
*/
|
||||
@Isolated
|
||||
public class InventoryTestIsolated extends AbstractTestCase {
|
||||
|
||||
public InventoryTestIsolated() {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSkipProductWithSerial() {
|
||||
Properties ctx = Env.getCtx();
|
||||
String trxName = getTrxName();
|
||||
|
||||
MWarehouse wh = new MWarehouse(Env.getCtx(), DictionaryIDs.M_Warehouse.HQ.id, null);
|
||||
boolean disallow = wh.isDisallowNegativeInv();
|
||||
MProduct product = null;
|
||||
try {
|
||||
|
||||
if (!disallow) {
|
||||
wh.setIsDisallowNegativeInv(true);
|
||||
wh.saveEx();
|
||||
CacheMgt.get().reset(MWarehouse.Table_Name, wh.get_ID());
|
||||
}
|
||||
|
||||
product = new MProduct(ctx, 0, null);
|
||||
product.setM_Product_Category_ID(DictionaryIDs.M_Product_Category.CHEMICALS.id);
|
||||
product.setName("testSkipProductWithSerial");
|
||||
product.setValue("testSkipProductWithSerial");
|
||||
product.setProductType(MProduct.PRODUCTTYPE_Item);
|
||||
product.setIsStocked(true);
|
||||
product.setIsSold(true);
|
||||
product.setIsPurchased(true);
|
||||
product.setC_UOM_ID(DictionaryIDs.C_UOM.EACH.id);
|
||||
product.setC_TaxCategory_ID(DictionaryIDs.C_TaxCategory.STANDARD.id);
|
||||
product.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.PATIO_CHAIR.id);
|
||||
product.saveEx();
|
||||
|
||||
MPriceListVersion plv = MPriceList.get(DictionaryIDs.M_PriceList.PURCHASE.id).getPriceListVersion(null);
|
||||
MProductPrice pp = new MProductPrice(Env.getCtx(), 0, getTrxName());
|
||||
pp.setM_PriceList_Version_ID(plv.getM_PriceList_Version_ID());
|
||||
pp.setM_Product_ID(product.get_ID());
|
||||
pp.setPriceStd(new BigDecimal("2"));
|
||||
pp.setPriceList(new BigDecimal("2"));
|
||||
pp.saveEx();
|
||||
|
||||
MAttributeSetInstance asi = new MAttributeSetInstance(Env.getCtx(), 0, getTrxName());
|
||||
asi.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.PATIO_CHAIR.id);
|
||||
asi.setSerNo("testSkipProductWithSerial #1");
|
||||
asi.saveEx();
|
||||
|
||||
createPOAndMRForProduct(product.get_ID(), asi);
|
||||
|
||||
MStorageOnHand[] onhands = MStorageOnHand.getOfProduct(Env.getCtx(), product.get_ID(), getTrxName());
|
||||
assertEquals(1, onhands.length, "Unexpected number of on hand records");
|
||||
assertEquals(onhands[0].getM_AttributeSetInstance_ID(), asi.get_ID(), "Unexpected M_AttributeSetInstance_ID for on hand record");
|
||||
|
||||
MInventory inventory = new MInventory(ctx, 0, trxName);
|
||||
inventory.setM_Warehouse_ID(DictionaryIDs.M_Warehouse.HQ.id);
|
||||
inventory.setC_DocType_ID(DictionaryIDs.C_DocType.MATERIAL_PHYSICAL_INVENTORY.id);
|
||||
inventory.saveEx();
|
||||
|
||||
MInventoryLine iline = new MInventoryLine(inventory,
|
||||
DictionaryIDs.M_Locator.HQ.id,
|
||||
product.getM_Product_ID(),
|
||||
0, // M_AttributeSetInstance_ID
|
||||
Env.ONE, // QtyBook
|
||||
Env.ZERO);
|
||||
iline.saveEx();
|
||||
|
||||
//should error out with negative on hand (skip the only asi record with serno)
|
||||
ProcessInfo info = MWorkflow.runDocumentActionWorkflow(inventory, DocAction.ACTION_Complete);
|
||||
assertTrue(info.isError(), info.getSummary());
|
||||
} finally {
|
||||
rollback();
|
||||
|
||||
if (product != null)
|
||||
product.deleteEx(true);
|
||||
|
||||
if (!disallow) {
|
||||
wh.setIsDisallowNegativeInv(false);
|
||||
wh.saveEx();
|
||||
CacheMgt.get().reset(MWarehouse.Table_Name, wh.get_ID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSkipProductWithSerial2() {
|
||||
Properties ctx = Env.getCtx();
|
||||
String trxName = getTrxName();
|
||||
|
||||
MWarehouse wh = new MWarehouse(Env.getCtx(), DictionaryIDs.M_Warehouse.HQ.id, null);
|
||||
boolean disallow = wh.isDisallowNegativeInv();
|
||||
MProduct product = null;
|
||||
try {
|
||||
|
||||
if (!disallow) {
|
||||
wh.setIsDisallowNegativeInv(true);
|
||||
wh.saveEx();
|
||||
CacheMgt.get().reset(MWarehouse.Table_Name, wh.get_ID());
|
||||
}
|
||||
|
||||
product = new MProduct(ctx, 0, null);
|
||||
product.setM_Product_Category_ID(DictionaryIDs.M_Product_Category.CHEMICALS.id);
|
||||
product.setName("testSkipProductWithSerial2");
|
||||
product.setValue("testSkipProductWithSerial2");
|
||||
product.setProductType(MProduct.PRODUCTTYPE_Item);
|
||||
product.setIsStocked(true);
|
||||
product.setIsSold(true);
|
||||
product.setIsPurchased(true);
|
||||
product.setC_UOM_ID(DictionaryIDs.C_UOM.EACH.id);
|
||||
product.setC_TaxCategory_ID(DictionaryIDs.C_TaxCategory.STANDARD.id);
|
||||
product.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.PATIO_CHAIR.id);
|
||||
product.saveEx();
|
||||
|
||||
MPriceListVersion plv = MPriceList.get(DictionaryIDs.M_PriceList.PURCHASE.id).getPriceListVersion(null);
|
||||
MProductPrice pp = new MProductPrice(Env.getCtx(), 0, getTrxName());
|
||||
pp.setM_PriceList_Version_ID(plv.getM_PriceList_Version_ID());
|
||||
pp.setM_Product_ID(product.get_ID());
|
||||
pp.setPriceStd(new BigDecimal("2"));
|
||||
pp.setPriceList(new BigDecimal("2"));
|
||||
pp.saveEx();
|
||||
|
||||
MAttributeSetInstance asi = new MAttributeSetInstance(Env.getCtx(), 0, getTrxName());
|
||||
asi.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.PATIO_CHAIR.id);
|
||||
asi.setSerNo("testSkipProductWithSerial2 #1");
|
||||
asi.saveEx();
|
||||
|
||||
createPOAndMRForProduct(product.get_ID(), asi);
|
||||
|
||||
MStorageOnHand[] onhands = MStorageOnHand.getOfProduct(Env.getCtx(), product.get_ID(), getTrxName());
|
||||
assertEquals(1, onhands.length, "Unexpected number of on hand records");
|
||||
assertEquals(onhands[0].getM_AttributeSetInstance_ID(), asi.get_ID(), "Unexpected M_AttributeSetInstance_ID for on hand record");
|
||||
|
||||
MAttributeSetInstance asi1 = new MAttributeSetInstance(Env.getCtx(), 0, getTrxName());
|
||||
asi1.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.PATIO_CHAIR.id);
|
||||
asi1.saveEx();
|
||||
|
||||
createPOAndMRForProduct(product.get_ID(), asi1);
|
||||
|
||||
onhands = MStorageOnHand.getOfProduct(Env.getCtx(), product.get_ID(), getTrxName());
|
||||
assertEquals(2, onhands.length, "Unexpected number of on hand records");
|
||||
Arrays.sort(onhands, new MStorageOnHand(Env.getCtx(), 0, null));
|
||||
assertEquals(onhands[0].getM_AttributeSetInstance_ID(), asi.get_ID(), "Unexpected M_AttributeSetInstance_ID for first on hand record");
|
||||
assertEquals(onhands[1].getM_AttributeSetInstance_ID(), asi1.get_ID(), "Unexpected M_AttributeSetInstance_ID for second on hand record");
|
||||
|
||||
MInventory inventory = new MInventory(ctx, 0, trxName);
|
||||
inventory.setM_Warehouse_ID(DictionaryIDs.M_Warehouse.HQ.id);
|
||||
inventory.setC_DocType_ID(DictionaryIDs.C_DocType.MATERIAL_PHYSICAL_INVENTORY.id);
|
||||
inventory.saveEx();
|
||||
|
||||
MInventoryLine iline = new MInventoryLine(inventory,
|
||||
DictionaryIDs.M_Locator.HQ.id,
|
||||
product.getM_Product_ID(),
|
||||
0, // M_AttributeSetInstance_ID
|
||||
new BigDecimal("2"), // QtyBook
|
||||
new BigDecimal("1"));
|
||||
iline.saveEx();
|
||||
|
||||
//should success with qty difference being applied to the asi with null serno record
|
||||
ProcessInfo info = MWorkflow.runDocumentActionWorkflow(inventory, DocAction.ACTION_Complete);
|
||||
assertFalse(info.isError(), info.getSummary());
|
||||
inventory.load(getTrxName());
|
||||
assertEquals(DocAction.STATUS_Completed, inventory.getDocStatus());
|
||||
|
||||
onhands = MStorageOnHand.getOfProduct(Env.getCtx(), product.get_ID(), getTrxName());
|
||||
assertEquals(2, onhands.length, "Unexpected number of on hand records");
|
||||
Arrays.sort(onhands, new MStorageOnHand(Env.getCtx(), 0, null));
|
||||
assertEquals(onhands[0].getM_AttributeSetInstance_ID(), asi.get_ID(), "Unexpected M_AttributeSetInstance_ID for first on hand record");
|
||||
assertEquals(onhands[1].getM_AttributeSetInstance_ID(), asi1.get_ID(), "Unexpected M_AttributeSetInstance_ID for second on hand record");
|
||||
assertEquals(1, onhands[0].getQtyOnHand().intValue());
|
||||
assertEquals(0, onhands[1].getQtyOnHand().intValue());
|
||||
} finally {
|
||||
rollback();
|
||||
|
||||
if (product != null)
|
||||
product.deleteEx(true);
|
||||
|
||||
if (!disallow) {
|
||||
wh.setIsDisallowNegativeInv(false);
|
||||
wh.saveEx();
|
||||
CacheMgt.get().reset(MWarehouse.Table_Name, wh.get_ID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void createPOAndMRForProduct(int productId, MAttributeSetInstance asi) {
|
||||
MOrder order = new MOrder(Env.getCtx(), 0, getTrxName());
|
||||
order.setBPartner(MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.PATIO.id));
|
||||
order.setC_DocTypeTarget_ID(DictionaryIDs.C_DocType.PURCHASE_ORDER.id);
|
||||
order.setIsSOTrx(false);
|
||||
order.setSalesRep_ID(DictionaryIDs.AD_User.GARDEN_ADMIN.id);
|
||||
order.setDocStatus(DocAction.STATUS_Drafted);
|
||||
order.setDocAction(DocAction.ACTION_Complete);
|
||||
Timestamp today = TimeUtil.getDay(System.currentTimeMillis());
|
||||
order.setDateOrdered(today);
|
||||
order.setDatePromised(today);
|
||||
order.saveEx();
|
||||
|
||||
MOrderLine line1 = new MOrderLine(order);
|
||||
line1.setLine(10);
|
||||
line1.setProduct(new MProduct(Env.getCtx(), productId, getTrxName()));
|
||||
line1.setQty(new BigDecimal("1"));
|
||||
line1.setDatePromised(today);
|
||||
line1.saveEx();
|
||||
|
||||
ProcessInfo info = MWorkflow.runDocumentActionWorkflow(order, DocAction.ACTION_Complete);
|
||||
assertFalse(info.isError(), info.getSummary());
|
||||
order.load(getTrxName());
|
||||
assertEquals(DocAction.STATUS_Completed, order.getDocStatus());
|
||||
|
||||
MInOut receipt1 = new MInOut(order, DictionaryIDs.C_DocType.MM_RECEIPT.id, order.getDateOrdered());
|
||||
receipt1.setDocStatus(DocAction.STATUS_Drafted);
|
||||
receipt1.setDocAction(DocAction.ACTION_Complete);
|
||||
receipt1.saveEx();
|
||||
|
||||
MInOutLine receiptLine1 = new MInOutLine(receipt1);
|
||||
receiptLine1.setOrderLine(line1, 0, new BigDecimal("1"));
|
||||
receiptLine1.setQty(new BigDecimal("1"));
|
||||
if (asi != null)
|
||||
receiptLine1.setM_AttributeSetInstance_ID(asi.get_ID());
|
||||
receiptLine1.saveEx();
|
||||
|
||||
info = MWorkflow.runDocumentActionWorkflow(receipt1, DocAction.ACTION_Complete);
|
||||
assertFalse(info.isError(), info.getSummary());
|
||||
receipt1.load(getTrxName());
|
||||
assertEquals(DocAction.STATUS_Completed, receipt1.getDocStatus());
|
||||
if (!receipt1.isPosted()) {
|
||||
String error = DocumentEngine.postImmediate(Env.getCtx(), receipt1.getAD_Client_ID(), receipt1.get_Table_ID(), receipt1.get_ID(), false, getTrxName());
|
||||
assertNull(error, error);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -60,10 +60,12 @@ import org.compiere.wf.MWorkflow;
|
|||
import org.idempiere.test.AbstractTestCase;
|
||||
import org.idempiere.test.DictionaryIDs;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.parallel.Isolated;
|
||||
|
||||
/**
|
||||
* @author Carlos Ruiz - globalqss
|
||||
*/
|
||||
@Isolated
|
||||
public class InvoiceCustomerTest extends AbstractTestCase {
|
||||
|
||||
public InvoiceCustomerTest() {
|
||||
|
@ -81,6 +83,9 @@ public class InvoiceCustomerTest extends AbstractTestCase {
|
|||
if (errorLogs != null)
|
||||
severeCount = errorLogs.length;
|
||||
|
||||
MBPartner bp = new MBPartner (Env.getCtx(), DictionaryIDs.C_BPartner.C_AND_W.id, getTrxName());
|
||||
DB.getDatabase().forUpdate(bp, 0);
|
||||
|
||||
// Invoice $200 today
|
||||
MInvoice invoice = new MInvoice(Env.getCtx(), 0, getTrxName());
|
||||
invoice.setBPartner(MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.C_AND_W.id)); // C&W
|
||||
|
|
|
@ -25,25 +25,16 @@
|
|||
package org.idempiere.test.model;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.List;
|
||||
|
||||
import org.compiere.model.MAttributeSet;
|
||||
import org.compiere.model.MAttributeSetInstance;
|
||||
import org.compiere.model.MLocator;
|
||||
import org.compiere.model.MPInstance;
|
||||
import org.compiere.model.MPInstancePara;
|
||||
import org.compiere.model.MProcess;
|
||||
import org.compiere.model.MProduct;
|
||||
import org.compiere.model.MStorageOnHand;
|
||||
import org.compiere.model.Query;
|
||||
import org.compiere.model.SystemIDs;
|
||||
import org.compiere.process.ProcessInfo;
|
||||
import org.compiere.process.ServerProcessCtl;
|
||||
import org.compiere.util.CacheMgt;
|
||||
import org.compiere.util.DB;
|
||||
import org.compiere.util.Env;
|
||||
|
@ -196,172 +187,5 @@ public class MStorageOnHandTest extends AbstractTestCase {
|
|||
MStorageOnHand.add(Env.getCtx(), hqLocator1.get_ID(), product.get_ID(), asi1.get_ID(), new BigDecimal("2"), today, getTrxName());
|
||||
M_Locator_ID = MStorageOnHand.getM_Locator_ID(hqLocator.getM_Warehouse_ID(), product.get_ID(), -1, new BigDecimal("1"), getTrxName());
|
||||
assertEquals(hqLocator1.get_ID(), M_Locator_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStorageCleanUp() {
|
||||
MProduct product = new MProduct(Env.getCtx(), 0, getTrxName());
|
||||
product.setName("testStorageCleanUp");
|
||||
product.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id);
|
||||
product.setIsStocked(true);
|
||||
product.setProductType(MProduct.PRODUCTTYPE_Item);
|
||||
product.setC_UOM_ID(DictionaryIDs.C_UOM.EACH.id);
|
||||
product.setM_Product_Category_ID(DictionaryIDs.M_Product_Category.CHEMICALS.id);
|
||||
product.setC_TaxCategory_ID(DictionaryIDs.C_TaxCategory.STANDARD.id);
|
||||
product.saveEx();
|
||||
|
||||
Timestamp today = TimeUtil.getDay(null);
|
||||
MStorageOnHand.add(Env.getCtx(), DictionaryIDs.M_Locator.HQ.id, product.get_ID(), 0, new BigDecimal("2"), today, getTrxName());
|
||||
Query query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=?", getTrxName());
|
||||
int count = query.setParameters(product.get_ID()).count();
|
||||
assertEquals(1, count);
|
||||
|
||||
MStorageOnHand.add(Env.getCtx(), DictionaryIDs.M_Locator.HQ.id, product.get_ID(), 0, new BigDecimal("-2"), today, getTrxName());
|
||||
DB.executeUpdateEx("UPDATE M_StorageOnHand SET Created=? WHERE M_Product_ID=?", new Object[] {TimeUtil.addDays(today, -7), product.get_ID()}, getTrxName());
|
||||
query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=?", getTrxName());
|
||||
count = query.setParameters(product.get_ID()).count();
|
||||
assertEquals(1, count);
|
||||
|
||||
//movement get product from cache
|
||||
MProduct product1 = new MProduct(Env.getCtx(), 0, null);
|
||||
product1.setName("testStorageCleanUp#1");
|
||||
product1.setValue(product1.getName());
|
||||
product1.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id);
|
||||
product1.setIsStocked(true);
|
||||
product1.setProductType(MProduct.PRODUCTTYPE_Item);
|
||||
product1.setC_UOM_ID(DictionaryIDs.C_UOM.EACH.id);
|
||||
product1.setM_Product_Category_ID(DictionaryIDs.M_Product_Category.CHEMICALS.id);
|
||||
product1.setC_TaxCategory_ID(DictionaryIDs.C_TaxCategory.STANDARD.id);
|
||||
product1.saveEx();
|
||||
|
||||
try {
|
||||
MAttributeSetInstance asi1 = new MAttributeSetInstance(Env.getCtx(), 0, getTrxName());
|
||||
asi1.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id);
|
||||
asi1.setLot("Lot1");
|
||||
asi1.saveEx();
|
||||
MStorageOnHand.add(Env.getCtx(), DictionaryIDs.M_Locator.HQ.id, product1.get_ID(), asi1.get_ID(), new BigDecimal("-1"), today, getTrxName());
|
||||
MStorageOnHand.add(Env.getCtx(), DictionaryIDs.M_Locator.HQ.id, product1.get_ID(), 0, new BigDecimal("1"), today, getTrxName());
|
||||
|
||||
query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=? AND M_AttributeSetInstance_ID=?", getTrxName());
|
||||
MStorageOnHand onhand = query.setParameters(product1.get_ID(), asi1.get_ID()).first();
|
||||
assertNotNull(onhand);
|
||||
assertEquals(-1, onhand.getQtyOnHand().intValue());
|
||||
|
||||
query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=? AND M_AttributeSetInstance_ID=?", getTrxName());
|
||||
onhand = query.setParameters(product1.get_ID(), 0).first();
|
||||
assertNotNull(onhand);
|
||||
assertEquals(1, onhand.getQtyOnHand().intValue());
|
||||
|
||||
MProduct product2 = new MProduct(Env.getCtx(), 0, getTrxName());
|
||||
product2.setName("testStorageCleanUp#2");
|
||||
product2.setValue(product2.getName());
|
||||
product2.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id);
|
||||
product2.setIsStocked(true);
|
||||
product2.setProductType(MProduct.PRODUCTTYPE_Item);
|
||||
product2.setC_UOM_ID(DictionaryIDs.C_UOM.EACH.id);
|
||||
product2.setM_Product_Category_ID(DictionaryIDs.M_Product_Category.CHEMICALS.id);
|
||||
product2.setC_TaxCategory_ID(DictionaryIDs.C_TaxCategory.STANDARD.id);
|
||||
product2.saveEx();
|
||||
|
||||
MAttributeSetInstance asi2 = new MAttributeSetInstance(Env.getCtx(), 0, getTrxName());
|
||||
asi2.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id);
|
||||
asi2.setLot("LotX");
|
||||
asi2.saveEx();
|
||||
MStorageOnHand.add(Env.getCtx(), DictionaryIDs.M_Locator.HQ.id, product2.get_ID(), asi2.get_ID(), new BigDecimal("-1"), today, getTrxName());
|
||||
|
||||
MAttributeSetInstance asi3 = new MAttributeSetInstance(Env.getCtx(), 0, getTrxName());
|
||||
asi3.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id);
|
||||
asi3.setLot("LotY");
|
||||
asi3.saveEx();
|
||||
MStorageOnHand.add(Env.getCtx(), DictionaryIDs.M_Locator.HQ.id, product2.get_ID(), asi3.get_ID(), new BigDecimal("1"), today, getTrxName());
|
||||
|
||||
query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=? AND M_AttributeSetInstance_ID=?", getTrxName());
|
||||
onhand = query.setParameters(product2.get_ID(), asi2.get_ID()).first();
|
||||
assertNotNull(onhand);
|
||||
assertEquals(-1, onhand.getQtyOnHand().intValue());
|
||||
|
||||
query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=? AND M_AttributeSetInstance_ID=?", getTrxName());
|
||||
onhand = query.setParameters(product2.get_ID(), asi3.get_ID()).first();
|
||||
assertNotNull(onhand);
|
||||
assertEquals(1, onhand.getQtyOnHand().intValue());
|
||||
|
||||
MProduct product3 = new MProduct(Env.getCtx(), 0, getTrxName());
|
||||
product3.setName("testStorageCleanUp#3");
|
||||
product3.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id);
|
||||
product3.setIsStocked(true);
|
||||
product3.setProductType(MProduct.PRODUCTTYPE_Item);
|
||||
product3.setC_UOM_ID(DictionaryIDs.C_UOM.EACH.id);
|
||||
product3.setM_Product_Category_ID(DictionaryIDs.M_Product_Category.CHEMICALS.id);
|
||||
product3.setC_TaxCategory_ID(DictionaryIDs.C_TaxCategory.STANDARD.id);
|
||||
product3.saveEx();
|
||||
|
||||
MAttributeSetInstance asi4 = new MAttributeSetInstance(Env.getCtx(), 0, getTrxName());
|
||||
asi4.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id);
|
||||
asi4.setSerNo(product3.getName()+"SerialNo#1");
|
||||
asi4.saveEx();
|
||||
MStorageOnHand.add(Env.getCtx(), DictionaryIDs.M_Locator.HQ.id, product3.get_ID(), asi4.get_ID(), new BigDecimal("1"), today, getTrxName());
|
||||
query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=?", getTrxName());
|
||||
count = query.setParameters(product3.get_ID()).count();
|
||||
assertEquals(1, count);
|
||||
|
||||
MStorageOnHand.add(Env.getCtx(), DictionaryIDs.M_Locator.HQ.id, product3.get_ID(), asi4.get_ID(), new BigDecimal("-1"), today, getTrxName());
|
||||
DB.executeUpdateEx("UPDATE M_StorageOnHand SET Created=? WHERE M_Product_ID=?", new Object[] {TimeUtil.addDays(today, -7), product3.get_ID()}, getTrxName());
|
||||
query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=?", getTrxName());
|
||||
count = query.setParameters(product3.get_ID()).count();
|
||||
assertEquals(1, count);
|
||||
|
||||
MPInstance instance = new MPInstance(Env.getCtx(), SystemIDs.PROCESS_M_StorageCleanup, 0);
|
||||
instance.saveEx();
|
||||
MPInstancePara para = new MPInstancePara(instance, 10);
|
||||
para.setParameterName("C_DocType_ID");
|
||||
para.setP_Number(DictionaryIDs.C_DocType.MATERIAL_MOVEMENT.id);
|
||||
para.saveEx();
|
||||
|
||||
MProcess process = MProcess.get(Env.getCtx(), SystemIDs.PROCESS_M_StorageCleanup);
|
||||
ProcessInfo pi = new ProcessInfo(process.getName(), process.get_ID());
|
||||
pi.setAD_PInstance_ID(instance.get_ID());
|
||||
pi.setAD_Client_ID(getAD_Client_ID());
|
||||
pi.setAD_User_ID(getAD_User_ID());
|
||||
pi.setTransactionName(getTrxName());
|
||||
ServerProcessCtl.process(pi, getTrx(), false);
|
||||
assertFalse(pi.isError(), pi.getSummary());
|
||||
|
||||
//check 0 stock removed
|
||||
query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=?", getTrxName());
|
||||
count = query.setParameters(product.get_ID()).count();
|
||||
assertEquals(0, count);
|
||||
|
||||
//check 0 stock with serno not removed
|
||||
query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=?", getTrxName());
|
||||
List<MStorageOnHand> onhands = query.setParameters(product3.get_ID()).list();
|
||||
assertEquals(1, onhands.size());
|
||||
assertEquals(0, onhands.get(0).getQtyOnHand().intValue());
|
||||
assertEquals(asi4.get_ID(), onhands.get(0).getM_AttributeSetInstance_ID());
|
||||
|
||||
//check -1 and 1 consolidated
|
||||
query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=? AND M_AttributeSetInstance_ID=?", getTrxName());
|
||||
onhand = query.setParameters(product1.get_ID(), asi1.get_ID()).first();
|
||||
assertNotNull(onhand);
|
||||
assertEquals(0, onhand.getQtyOnHand().intValue());
|
||||
|
||||
query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=? AND M_AttributeSetInstance_ID=?", getTrxName());
|
||||
onhand = query.setParameters(product1.get_ID(), 0).first();
|
||||
assertNotNull(onhand);
|
||||
assertEquals(0, onhand.getQtyOnHand().intValue());
|
||||
|
||||
//check -1 and 1 not consolidated due to different lot
|
||||
query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=? AND M_AttributeSetInstance_ID=?", getTrxName());
|
||||
onhand = query.setParameters(product2.get_ID(), asi2.get_ID()).first();
|
||||
assertNotNull(onhand);
|
||||
assertEquals(-1, onhand.getQtyOnHand().intValue());
|
||||
|
||||
query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=? AND M_AttributeSetInstance_ID=?", getTrxName());
|
||||
onhand = query.setParameters(product2.get_ID(), asi3.get_ID()).first();
|
||||
assertNotNull(onhand);
|
||||
assertEquals(1, onhand.getQtyOnHand().intValue());
|
||||
} finally {
|
||||
getTrx().rollback();
|
||||
product1.deleteEx(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,230 @@
|
|||
/***********************************************************************
|
||||
* This file is part of iDempiere ERP Open Source *
|
||||
* http://www.idempiere.org *
|
||||
* *
|
||||
* Copyright (C) Contributors *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software *
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
|
||||
* MA 02110-1301, USA. *
|
||||
* *
|
||||
* Contributors: *
|
||||
* - hengsin *
|
||||
**********************************************************************/
|
||||
package org.idempiere.test.model;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.List;
|
||||
|
||||
import org.compiere.model.MAttributeSetInstance;
|
||||
import org.compiere.model.MPInstance;
|
||||
import org.compiere.model.MPInstancePara;
|
||||
import org.compiere.model.MProcess;
|
||||
import org.compiere.model.MProduct;
|
||||
import org.compiere.model.MStorageOnHand;
|
||||
import org.compiere.model.Query;
|
||||
import org.compiere.model.SystemIDs;
|
||||
import org.compiere.process.ProcessInfo;
|
||||
import org.compiere.process.ServerProcessCtl;
|
||||
import org.compiere.util.DB;
|
||||
import org.compiere.util.Env;
|
||||
import org.compiere.util.TimeUtil;
|
||||
import org.idempiere.test.AbstractTestCase;
|
||||
import org.idempiere.test.DictionaryIDs;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.parallel.Isolated;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hengsin
|
||||
*
|
||||
*/
|
||||
@Isolated
|
||||
public class MStorageOnHandTestIsolated extends AbstractTestCase {
|
||||
|
||||
public MStorageOnHandTestIsolated() {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStorageCleanUp() {
|
||||
MProduct product = new MProduct(Env.getCtx(), 0, getTrxName());
|
||||
product.setName("testStorageCleanUp");
|
||||
product.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id);
|
||||
product.setIsStocked(true);
|
||||
product.setProductType(MProduct.PRODUCTTYPE_Item);
|
||||
product.setC_UOM_ID(DictionaryIDs.C_UOM.EACH.id);
|
||||
product.setM_Product_Category_ID(DictionaryIDs.M_Product_Category.CHEMICALS.id);
|
||||
product.setC_TaxCategory_ID(DictionaryIDs.C_TaxCategory.STANDARD.id);
|
||||
product.saveEx();
|
||||
|
||||
Timestamp today = TimeUtil.getDay(null);
|
||||
MStorageOnHand.add(Env.getCtx(), DictionaryIDs.M_Locator.HQ.id, product.get_ID(), 0, new BigDecimal("2"), today, getTrxName());
|
||||
Query query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=?", getTrxName());
|
||||
int count = query.setParameters(product.get_ID()).count();
|
||||
assertEquals(1, count);
|
||||
|
||||
MStorageOnHand.add(Env.getCtx(), DictionaryIDs.M_Locator.HQ.id, product.get_ID(), 0, new BigDecimal("-2"), today, getTrxName());
|
||||
DB.executeUpdateEx("UPDATE M_StorageOnHand SET Created=? WHERE M_Product_ID=?", new Object[] {TimeUtil.addDays(today, -7), product.get_ID()}, getTrxName());
|
||||
query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=?", getTrxName());
|
||||
count = query.setParameters(product.get_ID()).count();
|
||||
assertEquals(1, count);
|
||||
|
||||
//movement get product from cache
|
||||
MProduct product1 = new MProduct(Env.getCtx(), 0, null);
|
||||
product1.setName("testStorageCleanUp#1");
|
||||
product1.setValue(product1.getName());
|
||||
product1.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id);
|
||||
product1.setIsStocked(true);
|
||||
product1.setProductType(MProduct.PRODUCTTYPE_Item);
|
||||
product1.setC_UOM_ID(DictionaryIDs.C_UOM.EACH.id);
|
||||
product1.setM_Product_Category_ID(DictionaryIDs.M_Product_Category.CHEMICALS.id);
|
||||
product1.setC_TaxCategory_ID(DictionaryIDs.C_TaxCategory.STANDARD.id);
|
||||
product1.saveEx();
|
||||
|
||||
try {
|
||||
MAttributeSetInstance asi1 = new MAttributeSetInstance(Env.getCtx(), 0, getTrxName());
|
||||
asi1.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id);
|
||||
asi1.setLot("Lot1");
|
||||
asi1.saveEx();
|
||||
MStorageOnHand.add(Env.getCtx(), DictionaryIDs.M_Locator.HQ.id, product1.get_ID(), asi1.get_ID(), new BigDecimal("-1"), today, getTrxName());
|
||||
MStorageOnHand.add(Env.getCtx(), DictionaryIDs.M_Locator.HQ.id, product1.get_ID(), 0, new BigDecimal("1"), today, getTrxName());
|
||||
|
||||
query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=? AND M_AttributeSetInstance_ID=?", getTrxName());
|
||||
MStorageOnHand onhand = query.setParameters(product1.get_ID(), asi1.get_ID()).first();
|
||||
assertNotNull(onhand);
|
||||
assertEquals(-1, onhand.getQtyOnHand().intValue());
|
||||
|
||||
query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=? AND M_AttributeSetInstance_ID=?", getTrxName());
|
||||
onhand = query.setParameters(product1.get_ID(), 0).first();
|
||||
assertNotNull(onhand);
|
||||
assertEquals(1, onhand.getQtyOnHand().intValue());
|
||||
|
||||
MProduct product2 = new MProduct(Env.getCtx(), 0, getTrxName());
|
||||
product2.setName("testStorageCleanUp#2");
|
||||
product2.setValue(product2.getName());
|
||||
product2.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id);
|
||||
product2.setIsStocked(true);
|
||||
product2.setProductType(MProduct.PRODUCTTYPE_Item);
|
||||
product2.setC_UOM_ID(DictionaryIDs.C_UOM.EACH.id);
|
||||
product2.setM_Product_Category_ID(DictionaryIDs.M_Product_Category.CHEMICALS.id);
|
||||
product2.setC_TaxCategory_ID(DictionaryIDs.C_TaxCategory.STANDARD.id);
|
||||
product2.saveEx();
|
||||
|
||||
MAttributeSetInstance asi2 = new MAttributeSetInstance(Env.getCtx(), 0, getTrxName());
|
||||
asi2.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id);
|
||||
asi2.setLot("LotX");
|
||||
asi2.saveEx();
|
||||
MStorageOnHand.add(Env.getCtx(), DictionaryIDs.M_Locator.HQ.id, product2.get_ID(), asi2.get_ID(), new BigDecimal("-1"), today, getTrxName());
|
||||
|
||||
MAttributeSetInstance asi3 = new MAttributeSetInstance(Env.getCtx(), 0, getTrxName());
|
||||
asi3.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id);
|
||||
asi3.setLot("LotY");
|
||||
asi3.saveEx();
|
||||
MStorageOnHand.add(Env.getCtx(), DictionaryIDs.M_Locator.HQ.id, product2.get_ID(), asi3.get_ID(), new BigDecimal("1"), today, getTrxName());
|
||||
|
||||
query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=? AND M_AttributeSetInstance_ID=?", getTrxName());
|
||||
onhand = query.setParameters(product2.get_ID(), asi2.get_ID()).first();
|
||||
assertNotNull(onhand);
|
||||
assertEquals(-1, onhand.getQtyOnHand().intValue());
|
||||
|
||||
query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=? AND M_AttributeSetInstance_ID=?", getTrxName());
|
||||
onhand = query.setParameters(product2.get_ID(), asi3.get_ID()).first();
|
||||
assertNotNull(onhand);
|
||||
assertEquals(1, onhand.getQtyOnHand().intValue());
|
||||
|
||||
MProduct product3 = new MProduct(Env.getCtx(), 0, getTrxName());
|
||||
product3.setName("testStorageCleanUp#3");
|
||||
product3.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id);
|
||||
product3.setIsStocked(true);
|
||||
product3.setProductType(MProduct.PRODUCTTYPE_Item);
|
||||
product3.setC_UOM_ID(DictionaryIDs.C_UOM.EACH.id);
|
||||
product3.setM_Product_Category_ID(DictionaryIDs.M_Product_Category.CHEMICALS.id);
|
||||
product3.setC_TaxCategory_ID(DictionaryIDs.C_TaxCategory.STANDARD.id);
|
||||
product3.saveEx();
|
||||
|
||||
MAttributeSetInstance asi4 = new MAttributeSetInstance(Env.getCtx(), 0, getTrxName());
|
||||
asi4.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id);
|
||||
asi4.setSerNo(product3.getName()+"SerialNo#1");
|
||||
asi4.saveEx();
|
||||
MStorageOnHand.add(Env.getCtx(), DictionaryIDs.M_Locator.HQ.id, product3.get_ID(), asi4.get_ID(), new BigDecimal("1"), today, getTrxName());
|
||||
query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=?", getTrxName());
|
||||
count = query.setParameters(product3.get_ID()).count();
|
||||
assertEquals(1, count);
|
||||
|
||||
MStorageOnHand.add(Env.getCtx(), DictionaryIDs.M_Locator.HQ.id, product3.get_ID(), asi4.get_ID(), new BigDecimal("-1"), today, getTrxName());
|
||||
DB.executeUpdateEx("UPDATE M_StorageOnHand SET Created=? WHERE M_Product_ID=?", new Object[] {TimeUtil.addDays(today, -7), product3.get_ID()}, getTrxName());
|
||||
query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=?", getTrxName());
|
||||
count = query.setParameters(product3.get_ID()).count();
|
||||
assertEquals(1, count);
|
||||
|
||||
MPInstance instance = new MPInstance(Env.getCtx(), SystemIDs.PROCESS_M_StorageCleanup, 0);
|
||||
instance.saveEx();
|
||||
MPInstancePara para = new MPInstancePara(instance, 10);
|
||||
para.setParameterName("C_DocType_ID");
|
||||
para.setP_Number(DictionaryIDs.C_DocType.MATERIAL_MOVEMENT.id);
|
||||
para.saveEx();
|
||||
|
||||
MProcess process = MProcess.get(Env.getCtx(), SystemIDs.PROCESS_M_StorageCleanup);
|
||||
ProcessInfo pi = new ProcessInfo(process.getName(), process.get_ID());
|
||||
pi.setAD_PInstance_ID(instance.get_ID());
|
||||
pi.setAD_Client_ID(getAD_Client_ID());
|
||||
pi.setAD_User_ID(getAD_User_ID());
|
||||
pi.setTransactionName(getTrxName());
|
||||
ServerProcessCtl.process(pi, getTrx(), false);
|
||||
assertFalse(pi.isError(), pi.getSummary());
|
||||
|
||||
//check 0 stock removed
|
||||
query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=?", getTrxName());
|
||||
count = query.setParameters(product.get_ID()).count();
|
||||
assertEquals(0, count);
|
||||
|
||||
//check 0 stock with serno not removed
|
||||
query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=?", getTrxName());
|
||||
List<MStorageOnHand> onhands = query.setParameters(product3.get_ID()).list();
|
||||
assertEquals(1, onhands.size());
|
||||
assertEquals(0, onhands.get(0).getQtyOnHand().intValue());
|
||||
assertEquals(asi4.get_ID(), onhands.get(0).getM_AttributeSetInstance_ID());
|
||||
|
||||
//check -1 and 1 consolidated
|
||||
query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=? AND M_AttributeSetInstance_ID=?", getTrxName());
|
||||
onhand = query.setParameters(product1.get_ID(), asi1.get_ID()).first();
|
||||
assertNotNull(onhand);
|
||||
assertEquals(0, onhand.getQtyOnHand().intValue());
|
||||
|
||||
query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=? AND M_AttributeSetInstance_ID=?", getTrxName());
|
||||
onhand = query.setParameters(product1.get_ID(), 0).first();
|
||||
assertNotNull(onhand);
|
||||
assertEquals(0, onhand.getQtyOnHand().intValue());
|
||||
|
||||
//check -1 and 1 not consolidated due to different lot
|
||||
query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=? AND M_AttributeSetInstance_ID=?", getTrxName());
|
||||
onhand = query.setParameters(product2.get_ID(), asi2.get_ID()).first();
|
||||
assertNotNull(onhand);
|
||||
assertEquals(-1, onhand.getQtyOnHand().intValue());
|
||||
|
||||
query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=? AND M_AttributeSetInstance_ID=?", getTrxName());
|
||||
onhand = query.setParameters(product2.get_ID(), asi3.get_ID()).first();
|
||||
assertNotNull(onhand);
|
||||
assertEquals(1, onhand.getQtyOnHand().intValue());
|
||||
} finally {
|
||||
getTrx().rollback();
|
||||
product1.deleteEx(true);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -102,14 +102,14 @@ public class MTaxTest extends AbstractTestCase {
|
|||
bp.setIsTaxExempt(true);
|
||||
bp.saveEx();
|
||||
|
||||
int id = Core.getTaxLookup().get(Env.getCtx(), DictionaryIDs.M_Product.MULCH.id, 0, getLoginDate(), getLoginDate(), getAD_Org_ID(), getM_Warehouse_ID(),
|
||||
int id = Core.getTaxLookup().get(Env.getCtx(), DictionaryIDs.M_Product.AZALEA_BUSH.id, 0, getLoginDate(), getLoginDate(), getAD_Org_ID(), getM_Warehouse_ID(),
|
||||
bp.getPrimaryC_BPartner_Location_ID(), bp.getPrimaryC_BPartner_Location_ID(), true, null, getTrxName());
|
||||
assertEquals(taxExemptId, id, "Unexpected tax id");
|
||||
|
||||
bp.setIsTaxExempt(false);
|
||||
bp.saveEx();
|
||||
|
||||
id = Core.getTaxLookup().get(Env.getCtx(), DictionaryIDs.M_Product.MULCH.id, 0, getLoginDate(), getLoginDate(), getAD_Org_ID(), getM_Warehouse_ID(),
|
||||
id = Core.getTaxLookup().get(Env.getCtx(), DictionaryIDs.M_Product.AZALEA_BUSH.id, 0, getLoginDate(), getLoginDate(), getAD_Org_ID(), getM_Warehouse_ID(),
|
||||
bp.getPrimaryC_BPartner_Location_ID(), bp.getPrimaryC_BPartner_Location_ID(), true, null, getTrxName());
|
||||
assertTrue(id != taxExemptId, "Unexpected tax id: " + id);
|
||||
assertEquals(DictionaryIDs.C_Tax.STANDARD.id, id, "Unexpected tax id");
|
||||
|
@ -138,7 +138,7 @@ public class MTaxTest extends AbstractTestCase {
|
|||
CacheMgt.get().reset();
|
||||
|
||||
//need to create product with trx as order line get product from cache
|
||||
MProduct p = MProduct.get(DictionaryIDs.M_Product.MULCH.id);
|
||||
MProduct p = MProduct.get(DictionaryIDs.M_Product.AZALEA_BUSH.id);
|
||||
product = new MProduct(Env.getCtx(), 0, null);
|
||||
product.setM_Product_Category_ID(p.getM_Product_Category_ID());
|
||||
product.setC_TaxCategory_ID(category.get_ID());
|
||||
|
@ -281,7 +281,7 @@ public class MTaxTest extends AbstractTestCase {
|
|||
CacheMgt.get().reset();
|
||||
|
||||
//need to create product with trx as order line get product from cache
|
||||
MProduct p = MProduct.get(DictionaryIDs.M_Product.MULCH.id);
|
||||
MProduct p = MProduct.get(DictionaryIDs.M_Product.AZALEA_BUSH.id);
|
||||
product = new MProduct(Env.getCtx(), 0, null);
|
||||
product.setM_Product_Category_ID(p.getM_Product_Category_ID());
|
||||
product.setC_TaxCategory_ID(category.get_ID());
|
||||
|
|
|
@ -40,6 +40,7 @@ import org.compiere.model.Query;
|
|||
import org.compiere.util.Env;
|
||||
import org.idempiere.test.AbstractTestCase;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.parallel.Isolated;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
|
||||
import org.springframework.core.type.filter.AssignableTypeFilter;
|
||||
|
@ -48,6 +49,7 @@ import org.springframework.core.type.filter.AssignableTypeFilter;
|
|||
* @author hengsin
|
||||
*
|
||||
*/
|
||||
@Isolated
|
||||
public class ModelClassMappingTest extends AbstractTestCase {
|
||||
|
||||
//copy from DefaultModelFactory
|
||||
|
|
|
@ -31,26 +31,17 @@ import static org.junit.jupiter.api.Assertions.assertNull;
|
|||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.List;
|
||||
|
||||
import org.compiere.model.MAccount;
|
||||
import org.compiere.model.MAcctSchema;
|
||||
import org.compiere.model.MAttributeSetInstance;
|
||||
import org.compiere.model.MBPartner;
|
||||
import org.compiere.model.MClient;
|
||||
import org.compiere.model.MCost;
|
||||
import org.compiere.model.MCostElement;
|
||||
import org.compiere.model.MFactAcct;
|
||||
import org.compiere.model.MInOut;
|
||||
import org.compiere.model.MInOutLine;
|
||||
import org.compiere.model.MInventory;
|
||||
import org.compiere.model.MInventoryLine;
|
||||
import org.compiere.model.MOrder;
|
||||
import org.compiere.model.MOrderLine;
|
||||
import org.compiere.model.MPInstance;
|
||||
import org.compiere.model.MPInstancePara;
|
||||
import org.compiere.model.MPriceList;
|
||||
import org.compiere.model.MPriceListVersion;
|
||||
import org.compiere.model.MProcess;
|
||||
|
@ -61,7 +52,6 @@ import org.compiere.model.MProductPrice;
|
|||
import org.compiere.model.MProduction;
|
||||
import org.compiere.model.MProductionLine;
|
||||
import org.compiere.model.MStorageOnHand;
|
||||
import org.compiere.model.ProductCost;
|
||||
import org.compiere.model.Query;
|
||||
import org.compiere.process.DocAction;
|
||||
import org.compiere.process.DocumentEngine;
|
||||
|
@ -83,97 +73,6 @@ import org.junit.jupiter.api.Test;
|
|||
*
|
||||
*/
|
||||
public class ProductionTest extends AbstractTestCase {
|
||||
|
||||
@Test
|
||||
public void testAverageCostingProduction() {
|
||||
int mulchId = 137;
|
||||
int hqLocator = 101;
|
||||
|
||||
createPOAndMRForProduct(mulchId);
|
||||
|
||||
MProduct mulch = MProduct.get(mulchId);
|
||||
BigDecimal componentOnHand1 = MStorageOnHand.getQtyOnHand(mulchId, getM_Warehouse_ID(), 0, getTrxName());
|
||||
BigDecimal componentCost = MCost.getCurrentCost(mulch, 0, getTrxName());
|
||||
|
||||
MProduct mulchX = new MProduct(Env.getCtx(), 0, getTrxName());
|
||||
mulchX.setName("Mulch X");
|
||||
mulchX.setIsBOM(true);
|
||||
mulchX.setIsStocked(true);
|
||||
mulchX.setC_UOM_ID(mulch.getC_UOM_ID());
|
||||
mulchX.setM_Product_Category_ID(mulch.getM_Product_Category_ID());
|
||||
mulchX.setProductType(mulch.getProductType());
|
||||
mulchX.setM_AttributeSet_ID(mulch.getM_AttributeSet_ID());
|
||||
mulchX.setC_TaxCategory_ID(mulch.getC_TaxCategory_ID());
|
||||
mulchX.saveEx();
|
||||
BigDecimal endProductOnHand1 = MStorageOnHand.getQtyOnHand(mulchX.get_ID(), getM_Warehouse_ID(), 0, getTrxName());
|
||||
|
||||
MPPProductBOM bom = new MPPProductBOM(Env.getCtx(), 0, getTrxName());
|
||||
bom.setM_Product_ID(mulchX.get_ID());
|
||||
bom.setBOMType(MPPProductBOM.BOMTYPE_CurrentActive);
|
||||
bom.setBOMUse(MPPProductBOM.BOMUSE_Master);
|
||||
bom.setName(mulchX.getName());
|
||||
bom.saveEx();
|
||||
|
||||
MPPProductBOMLine line = new MPPProductBOMLine(bom);
|
||||
line.setM_Product_ID(mulchId);
|
||||
line.setQtyBOM(new BigDecimal("1"));
|
||||
line.saveEx();
|
||||
|
||||
mulchX.load(getTrxName());
|
||||
mulchX.setIsVerified(true);
|
||||
mulchX.saveEx();
|
||||
|
||||
MProduction production = new MProduction(Env.getCtx(), 0, getTrxName());
|
||||
production.setM_Product_ID(mulchX.get_ID());
|
||||
production.setM_Locator_ID(hqLocator);
|
||||
production.setIsUseProductionPlan(false);
|
||||
production.setMovementDate(getLoginDate());
|
||||
production.setDocAction(DocAction.ACTION_Complete);
|
||||
production.setDocStatus(DocAction.STATUS_Drafted);
|
||||
production.setIsComplete(false);
|
||||
production.setProductionQty(new BigDecimal("1"));
|
||||
production.setPP_Product_BOM_ID(bom.getPP_Product_BOM_ID());
|
||||
production.saveEx();
|
||||
|
||||
int productionCreate = 53226;
|
||||
MProcess process = MProcess.get(Env.getCtx(), productionCreate);
|
||||
ProcessInfo pi = new ProcessInfo(process.getName(), process.get_ID());
|
||||
pi.setAD_Client_ID(getAD_Client_ID());
|
||||
pi.setAD_User_ID(getAD_User_ID());
|
||||
pi.setRecord_ID(production.get_ID());
|
||||
pi.setTransactionName(getTrxName());
|
||||
ServerProcessCtl.process(pi, getTrx(), false);
|
||||
assertFalse(pi.isError(), pi.getSummary());
|
||||
|
||||
production.load(getTrxName());
|
||||
assertEquals("Y", production.getIsCreated(), "MProduction.IsCreated != Y");
|
||||
assertTrue(production.getLines().length > 0, "No Production Lines");
|
||||
|
||||
ProcessInfo info = MWorkflow.runDocumentActionWorkflow(production, DocAction.ACTION_Complete);
|
||||
production.load(getTrxName());
|
||||
assertFalse(info.isError(), info.getSummary());
|
||||
assertEquals(DocAction.STATUS_Completed, production.getDocStatus(), "Production Status="+production.getDocStatus());
|
||||
|
||||
BigDecimal componentOnHand2 = MStorageOnHand.getQtyOnHand(mulchId, getM_Warehouse_ID(), 0, getTrxName());
|
||||
BigDecimal endProductOnHand2 = MStorageOnHand.getQtyOnHand(mulchX.get_ID(), getM_Warehouse_ID(), 0, getTrxName());
|
||||
|
||||
BigDecimal componentChange = componentOnHand2.subtract(componentOnHand1).setScale(0);
|
||||
BigDecimal endProductChange = endProductOnHand2.subtract(endProductOnHand1).setScale(0);
|
||||
assertEquals(new BigDecimal("-1"), componentChange, "On hand of component doesn't reduce as expected");
|
||||
assertEquals(new BigDecimal("1"), endProductChange, "On hand of end product doesn't increase as expected");
|
||||
|
||||
if (!production.isPosted()) {
|
||||
String msg = DocumentEngine.postImmediate(Env.getCtx(), getAD_Client_ID(), MProduction.Table_ID, production.get_ID(), false, getTrxName());
|
||||
assertNull(msg, msg);
|
||||
}
|
||||
|
||||
BigDecimal endProductCost = MCost.getCurrentCost(mulchX, 0, getTrxName());
|
||||
MAcctSchema as = MClient.get(getAD_Client_ID()).getAcctSchema();
|
||||
componentCost = componentCost.setScale(as.getCostingPrecision(), RoundingMode.HALF_UP);
|
||||
endProductCost = endProductCost.setScale(as.getCostingPrecision(), RoundingMode.HALF_UP);
|
||||
assertEquals(componentCost, endProductCost, "Cost not roll up correctly");
|
||||
}
|
||||
|
||||
// creates an order and material receipt for qty 25 at special price of 2.60 each
|
||||
private void createPOAndMRForProduct(int mulchId) {
|
||||
MOrder order = new MOrder(Env.getCtx(), 0, getTrxName());
|
||||
|
@ -220,243 +119,7 @@ public class ProductionTest extends AbstractTestCase {
|
|||
assertNull(error, error);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStandardCostingProduction() {
|
||||
MProductCategory category = new MProductCategory(Env.getCtx(), 0, null);
|
||||
category.setName("Standard Costing");
|
||||
category.saveEx();
|
||||
|
||||
String whereClause = "M_Product_Category_ID=?";
|
||||
List<MProductCategoryAcct> categoryAccts = new Query(Env.getCtx(), MProductCategoryAcct.Table_Name, whereClause, null)
|
||||
.setParameters(category.get_ID())
|
||||
.list();
|
||||
for (MProductCategoryAcct categoryAcct : categoryAccts) {
|
||||
categoryAcct.setCostingMethod(MAcctSchema.COSTINGMETHOD_StandardCosting);
|
||||
categoryAcct.saveEx();
|
||||
}
|
||||
// ProductCost api doesn't use trx to retrieve product
|
||||
int mulchId = 137;
|
||||
MProduct mulch = new MProduct(Env.getCtx(), mulchId, null);
|
||||
int categorySaveId = mulch.getM_Product_Category_ID();
|
||||
mulch.setM_Product_Category_ID(category.get_ID());
|
||||
mulch.saveEx();
|
||||
|
||||
try {
|
||||
int hqLocator = 101;
|
||||
createPOAndMRForProduct(mulchId);
|
||||
|
||||
BigDecimal componentOnHand1 = MStorageOnHand.getQtyOnHand(mulchId, getM_Warehouse_ID(), 0, getTrxName());
|
||||
BigDecimal componentCost = MCost.getCurrentCost(mulch, 0, getTrxName());
|
||||
|
||||
MProduct mulchX = new MProduct(Env.getCtx(), 0, getTrxName());
|
||||
mulchX.setName("Mulch X");
|
||||
mulchX.setIsBOM(true);
|
||||
mulchX.setIsStocked(true);
|
||||
mulchX.setC_UOM_ID(mulch.getC_UOM_ID());
|
||||
mulchX.setM_Product_Category_ID(category.getM_Product_Category_ID());
|
||||
mulchX.setProductType(mulch.getProductType());
|
||||
mulchX.setM_AttributeSet_ID(mulch.getM_AttributeSet_ID());
|
||||
mulchX.setC_TaxCategory_ID(mulch.getC_TaxCategory_ID());
|
||||
mulchX.saveEx();
|
||||
BigDecimal endProductOnHand1 = MStorageOnHand.getQtyOnHand(mulchX.get_ID(), getM_Warehouse_ID(), 0, getTrxName());
|
||||
|
||||
int costAdjustmentDocTypeId = 200004;
|
||||
MInventory inventory = new MInventory(Env.getCtx(), 0, getTrxName());
|
||||
inventory.setCostingMethod(MAcctSchema.COSTINGMETHOD_StandardCosting);
|
||||
inventory.setC_DocType_ID(costAdjustmentDocTypeId);
|
||||
inventory.setM_Warehouse_ID(getM_Warehouse_ID());
|
||||
inventory.setMovementDate(getLoginDate());
|
||||
inventory.setDocAction(DocAction.ACTION_Complete);
|
||||
inventory.saveEx();
|
||||
|
||||
MAcctSchema as = MClient.get(getAD_Client_ID()).getAcctSchema();
|
||||
BigDecimal endProductCost = new BigDecimal("2.50").setScale(as.getCostingPrecision(), RoundingMode.HALF_UP);
|
||||
MInventoryLine il = new MInventoryLine(Env.getCtx(), 0, getTrxName());
|
||||
il.setM_Inventory_ID(inventory.get_ID());
|
||||
il.setM_Locator_ID(hqLocator);
|
||||
il.setM_Product_ID(mulchX.getM_Product_ID());
|
||||
il.setCurrentCostPrice(new BigDecimal("0"));
|
||||
il.setNewCostPrice(endProductCost);
|
||||
il.saveEx();
|
||||
|
||||
ProcessInfo info = MWorkflow.runDocumentActionWorkflow(inventory, DocAction.ACTION_Complete);
|
||||
inventory.load(getTrxName());
|
||||
assertFalse(info.isError(), info.getSummary());
|
||||
assertEquals(DocAction.STATUS_Completed, inventory.getDocStatus(), "Cost Adjustment Status="+inventory.getDocStatus());
|
||||
|
||||
if (!inventory.isPosted()) {
|
||||
String msg = DocumentEngine.postImmediate(Env.getCtx(), getAD_Client_ID(), MInventory.Table_ID, inventory.get_ID(), false, getTrxName());
|
||||
assertNull(msg, msg);
|
||||
}
|
||||
BigDecimal adjusted = MCost.getCurrentCost(mulchX, 0, getTrxName()).setScale(as.getCostingPrecision(), RoundingMode.HALF_UP);
|
||||
assertEquals(endProductCost, adjusted, "Cost not adjusted: " + adjusted.toPlainString());
|
||||
|
||||
MPPProductBOM bom = new MPPProductBOM(Env.getCtx(), 0, getTrxName());
|
||||
bom.setM_Product_ID(mulchX.get_ID());
|
||||
bom.setBOMType(MPPProductBOM.BOMTYPE_CurrentActive);
|
||||
bom.setBOMUse(MPPProductBOM.BOMUSE_Master);
|
||||
bom.setName(mulchX.getName());
|
||||
bom.saveEx();
|
||||
|
||||
MPPProductBOMLine line = new MPPProductBOMLine(bom);
|
||||
line.setM_Product_ID(mulchId);
|
||||
line.setQtyBOM(new BigDecimal("1"));
|
||||
line.saveEx();
|
||||
|
||||
mulchX.load(getTrxName());
|
||||
mulchX.setIsVerified(true);
|
||||
mulchX.saveEx();
|
||||
|
||||
MProduction production = new MProduction(Env.getCtx(), 0, getTrxName());
|
||||
production.setM_Product_ID(mulchX.get_ID());
|
||||
production.setM_Locator_ID(hqLocator);
|
||||
production.setIsUseProductionPlan(false);
|
||||
production.setMovementDate(getLoginDate());
|
||||
production.setDocAction(DocAction.ACTION_Complete);
|
||||
production.setDocStatus(DocAction.STATUS_Drafted);
|
||||
production.setIsComplete(false);
|
||||
production.setProductionQty(new BigDecimal("1"));
|
||||
production.setPP_Product_BOM_ID(bom.getPP_Product_BOM_ID());
|
||||
production.saveEx();
|
||||
|
||||
int productionCreate = 53226;
|
||||
MProcess process = MProcess.get(Env.getCtx(), productionCreate);
|
||||
ProcessInfo pi = new ProcessInfo(process.getName(), process.get_ID());
|
||||
pi.setAD_Client_ID(getAD_Client_ID());
|
||||
pi.setAD_User_ID(getAD_User_ID());
|
||||
pi.setRecord_ID(production.get_ID());
|
||||
pi.setTransactionName(getTrxName());
|
||||
ServerProcessCtl.process(pi, getTrx(), false);
|
||||
assertFalse(pi.isError(), pi.getSummary());
|
||||
|
||||
production.load(getTrxName());
|
||||
assertEquals("Y", production.getIsCreated(), "MProduction.IsCreated != Y");
|
||||
assertTrue(production.getLines().length > 0, "No Production Lines");
|
||||
|
||||
info = MWorkflow.runDocumentActionWorkflow(production, DocAction.ACTION_Complete);
|
||||
production.load(getTrxName());
|
||||
assertFalse(info.isError(), info.getSummary());
|
||||
assertEquals(DocAction.STATUS_Completed, production.getDocStatus(), "Production Status="+production.getDocStatus());
|
||||
|
||||
BigDecimal componentOnHand2 = MStorageOnHand.getQtyOnHand(mulchId, getM_Warehouse_ID(), 0, getTrxName());
|
||||
BigDecimal endProductOnHand2 = MStorageOnHand.getQtyOnHand(mulchX.get_ID(), getM_Warehouse_ID(), 0, getTrxName());
|
||||
BigDecimal componentChange = componentOnHand2.subtract(componentOnHand1).setScale(0);
|
||||
BigDecimal endProductChange = endProductOnHand2.subtract(endProductOnHand1).setScale(0);
|
||||
|
||||
assertEquals(componentChange, new BigDecimal("-1"), "On hand of component doesn't reduce as expected");
|
||||
assertEquals(endProductChange, new BigDecimal("1"), "On hand of end product doesn't increase as expected");
|
||||
|
||||
if (!production.isPosted()) {
|
||||
String msg = DocumentEngine.postImmediate(Env.getCtx(), getAD_Client_ID(), MProduction.Table_ID, production.get_ID(), false, getTrxName());
|
||||
assertNull(msg, msg);
|
||||
}
|
||||
|
||||
BigDecimal endProductCost1 = MCost.getCurrentCost(mulchX, 0, getTrxName()).setScale(as.getCostingPrecision(), RoundingMode.HALF_UP);
|
||||
assertEquals(endProductCost, endProductCost1, "Standard Cost Changed");
|
||||
|
||||
ProductCost pc = new ProductCost (Env.getCtx(), mulchX.getM_Product_ID(), 0, getTrxName());
|
||||
MAccount acctVariance = pc.getAccount(ProductCost.ACCTTYPE_P_RateVariance, as);
|
||||
|
||||
whereClause = MFactAcct.COLUMNNAME_AD_Table_ID + "=" + MProduction.Table_ID
|
||||
+ " AND " + MFactAcct.COLUMNNAME_Record_ID + "=" + production.get_ID()
|
||||
+ " AND " + MFactAcct.COLUMNNAME_C_AcctSchema_ID + "=" + as.getC_AcctSchema_ID()
|
||||
+ " AND " + MFactAcct.COLUMNNAME_Account_ID + "=" + acctVariance.getAccount_ID();
|
||||
int[] ids = MFactAcct.getAllIDs(MFactAcct.Table_Name, whereClause, getTrxName());
|
||||
BigDecimal variance = BigDecimal.ZERO;
|
||||
for (int id : ids) {
|
||||
MFactAcct fa = new MFactAcct(Env.getCtx(), id, getTrxName());
|
||||
variance = fa.getAmtAcctDr().subtract(fa.getAmtAcctCr());
|
||||
break;
|
||||
}
|
||||
BigDecimal varianceExpected = componentCost.subtract(endProductCost).setScale(as.getStdPrecision(), RoundingMode.HALF_UP);
|
||||
assertEquals(varianceExpected.setScale(2, RoundingMode.HALF_UP), variance.setScale(2, RoundingMode.HALF_UP), "Variance not posted correctly.");
|
||||
} finally {
|
||||
getTrx().rollback();
|
||||
mulch.setM_Product_Category_ID(categorySaveId);
|
||||
mulch.saveEx();
|
||||
category.deleteEx(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRollUp() {
|
||||
MProductCategory category = new MProductCategory(Env.getCtx(), 0, null);
|
||||
category.setName("Standard Costing");
|
||||
category.saveEx();
|
||||
|
||||
String whereClause = "M_Product_Category_ID=?";
|
||||
List<MProductCategoryAcct> categoryAccts = new Query(Env.getCtx(), MProductCategoryAcct.Table_Name, whereClause, null)
|
||||
.setParameters(category.get_ID())
|
||||
.list();
|
||||
for (MProductCategoryAcct categoryAcct : categoryAccts) {
|
||||
categoryAcct.setCostingMethod(MAcctSchema.COSTINGMETHOD_StandardCosting);
|
||||
categoryAcct.saveEx();
|
||||
}
|
||||
|
||||
try {
|
||||
int rollUpProcessId = 53230;
|
||||
int mulchId = 137;
|
||||
MProduct mulch = new MProduct(Env.getCtx(), mulchId, getTrxName());
|
||||
mulch.setM_Product_Category_ID(category.get_ID());
|
||||
mulch.saveEx();
|
||||
|
||||
MAcctSchema as = MClient.get(getAD_Client_ID()).getAcctSchema();
|
||||
BigDecimal componentCost = MCost.getCurrentCost(mulch, 0, getTrxName()).setScale(as.getCostingPrecision(), RoundingMode.HALF_UP);
|
||||
|
||||
MProduct mulchX = new MProduct(Env.getCtx(), 0, getTrxName());
|
||||
mulchX.setName("Mulch X");
|
||||
mulchX.setIsBOM(true);
|
||||
mulchX.setIsStocked(true);
|
||||
mulchX.setC_UOM_ID(mulch.getC_UOM_ID());
|
||||
mulchX.setM_Product_Category_ID(category.getM_Product_Category_ID());
|
||||
mulchX.setProductType(mulch.getProductType());
|
||||
mulchX.setM_AttributeSet_ID(mulch.getM_AttributeSet_ID());
|
||||
mulchX.setC_TaxCategory_ID(mulch.getC_TaxCategory_ID());
|
||||
mulchX.saveEx();
|
||||
|
||||
MPPProductBOM bom = new MPPProductBOM(Env.getCtx(), 0, getTrxName());
|
||||
bom.setM_Product_ID(mulchX.get_ID());
|
||||
bom.setBOMType(MPPProductBOM.BOMTYPE_CurrentActive);
|
||||
bom.setBOMUse(MPPProductBOM.BOMUSE_Master);
|
||||
bom.setName(mulchX.getName());
|
||||
bom.saveEx();
|
||||
|
||||
MPPProductBOMLine line = new MPPProductBOMLine(bom);
|
||||
line.setM_Product_ID(mulchId);
|
||||
line.setQtyBOM(new BigDecimal("1"));
|
||||
line.saveEx();
|
||||
|
||||
mulchX.load(getTrxName());
|
||||
mulchX.setIsVerified(true);
|
||||
mulchX.saveEx();
|
||||
|
||||
MPInstance instance = new MPInstance(Env.getCtx(), rollUpProcessId, 0);
|
||||
instance.saveEx();
|
||||
MPInstancePara para = new MPInstancePara(instance, 10);
|
||||
para.setParameterName("M_Product_ID");
|
||||
para.setP_Number(mulchX.get_ID());
|
||||
para.saveEx();
|
||||
|
||||
para = new MPInstancePara(instance, 20);
|
||||
para.setParameterName("M_CostElement_ID");
|
||||
para.setP_Number(MCostElement.getMaterialCostElement(Env.getCtx(), MAcctSchema.COSTINGMETHOD_StandardCosting).get_ID());
|
||||
para.saveEx();
|
||||
|
||||
ProcessInfo info = new ProcessInfo(MProcess.get(rollUpProcessId).getName(), rollUpProcessId);
|
||||
info.setAD_PInstance_ID(instance.getAD_PInstance_ID());
|
||||
info.setTransactionName(getTrxName());
|
||||
ServerProcessCtl.process(info, getTrx(), false);
|
||||
assertFalse(info.isError(), info.getSummary());
|
||||
|
||||
BigDecimal endProductCost = MCost.getCurrentCost(mulchX, 0, getTrxName()).setScale(as.getCostingPrecision(), RoundingMode.HALF_UP);;
|
||||
assertEquals(componentCost, endProductCost, "BOM Cost not roll up.");
|
||||
} finally {
|
||||
getTrx().rollback();
|
||||
category.deleteEx(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAutoProduce() {
|
||||
int mulchId = 137;
|
||||
|
|
|
@ -0,0 +1,460 @@
|
|||
/***********************************************************************
|
||||
* This file is part of iDempiere ERP Open Source *
|
||||
* http://www.idempiere.org *
|
||||
* *
|
||||
* Copyright (C) Contributors *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software *
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
|
||||
* MA 02110-1301, USA. *
|
||||
* *
|
||||
* Contributors: *
|
||||
* - hengsin *
|
||||
**********************************************************************/
|
||||
package org.idempiere.test.model;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.List;
|
||||
|
||||
import org.compiere.model.MAccount;
|
||||
import org.compiere.model.MAcctSchema;
|
||||
import org.compiere.model.MBPartner;
|
||||
import org.compiere.model.MClient;
|
||||
import org.compiere.model.MCost;
|
||||
import org.compiere.model.MCostElement;
|
||||
import org.compiere.model.MFactAcct;
|
||||
import org.compiere.model.MInOut;
|
||||
import org.compiere.model.MInOutLine;
|
||||
import org.compiere.model.MInventory;
|
||||
import org.compiere.model.MInventoryLine;
|
||||
import org.compiere.model.MOrder;
|
||||
import org.compiere.model.MOrderLine;
|
||||
import org.compiere.model.MPInstance;
|
||||
import org.compiere.model.MPInstancePara;
|
||||
import org.compiere.model.MProcess;
|
||||
import org.compiere.model.MProduct;
|
||||
import org.compiere.model.MProductCategory;
|
||||
import org.compiere.model.MProductCategoryAcct;
|
||||
import org.compiere.model.MProduction;
|
||||
import org.compiere.model.MStorageOnHand;
|
||||
import org.compiere.model.ProductCost;
|
||||
import org.compiere.model.Query;
|
||||
import org.compiere.process.DocAction;
|
||||
import org.compiere.process.DocumentEngine;
|
||||
import org.compiere.process.ProcessInfo;
|
||||
import org.compiere.process.ServerProcessCtl;
|
||||
import org.compiere.util.Env;
|
||||
import org.compiere.util.TimeUtil;
|
||||
import org.compiere.wf.MWorkflow;
|
||||
import org.eevolution.model.MPPProductBOM;
|
||||
import org.eevolution.model.MPPProductBOMLine;
|
||||
import org.idempiere.test.AbstractTestCase;
|
||||
import org.idempiere.test.DictionaryIDs;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.parallel.Execution;
|
||||
import org.junit.jupiter.api.parallel.ExecutionMode;
|
||||
import org.junit.jupiter.api.parallel.Isolated;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hengsin
|
||||
*
|
||||
*/
|
||||
@Isolated
|
||||
@Execution(ExecutionMode.SAME_THREAD)
|
||||
public class ProductionTestIsolated extends AbstractTestCase {
|
||||
|
||||
public ProductionTestIsolated() {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAverageCostingProduction() {
|
||||
int mulchId = 137;
|
||||
int hqLocator = 101;
|
||||
|
||||
createPOAndMRForProduct(mulchId);
|
||||
|
||||
MProduct mulch = MProduct.get(mulchId);
|
||||
BigDecimal componentOnHand1 = MStorageOnHand.getQtyOnHand(mulchId, getM_Warehouse_ID(), 0, getTrxName());
|
||||
BigDecimal componentCost = MCost.getCurrentCost(mulch, 0, getTrxName());
|
||||
|
||||
MProduct mulchX = new MProduct(Env.getCtx(), 0, getTrxName());
|
||||
mulchX.setName("Mulch X");
|
||||
mulchX.setIsBOM(true);
|
||||
mulchX.setIsStocked(true);
|
||||
mulchX.setC_UOM_ID(mulch.getC_UOM_ID());
|
||||
mulchX.setM_Product_Category_ID(mulch.getM_Product_Category_ID());
|
||||
mulchX.setProductType(mulch.getProductType());
|
||||
mulchX.setM_AttributeSet_ID(mulch.getM_AttributeSet_ID());
|
||||
mulchX.setC_TaxCategory_ID(mulch.getC_TaxCategory_ID());
|
||||
mulchX.saveEx();
|
||||
BigDecimal endProductOnHand1 = MStorageOnHand.getQtyOnHand(mulchX.get_ID(), getM_Warehouse_ID(), 0, getTrxName());
|
||||
|
||||
MPPProductBOM bom = new MPPProductBOM(Env.getCtx(), 0, getTrxName());
|
||||
bom.setM_Product_ID(mulchX.get_ID());
|
||||
bom.setBOMType(MPPProductBOM.BOMTYPE_CurrentActive);
|
||||
bom.setBOMUse(MPPProductBOM.BOMUSE_Master);
|
||||
bom.setName(mulchX.getName());
|
||||
bom.saveEx();
|
||||
|
||||
MPPProductBOMLine line = new MPPProductBOMLine(bom);
|
||||
line.setM_Product_ID(mulchId);
|
||||
line.setQtyBOM(new BigDecimal("1"));
|
||||
line.saveEx();
|
||||
|
||||
mulchX.load(getTrxName());
|
||||
mulchX.setIsVerified(true);
|
||||
mulchX.saveEx();
|
||||
|
||||
MProduction production = new MProduction(Env.getCtx(), 0, getTrxName());
|
||||
production.setM_Product_ID(mulchX.get_ID());
|
||||
production.setM_Locator_ID(hqLocator);
|
||||
production.setIsUseProductionPlan(false);
|
||||
production.setMovementDate(getLoginDate());
|
||||
production.setDocAction(DocAction.ACTION_Complete);
|
||||
production.setDocStatus(DocAction.STATUS_Drafted);
|
||||
production.setIsComplete(false);
|
||||
production.setProductionQty(new BigDecimal("1"));
|
||||
production.setPP_Product_BOM_ID(bom.getPP_Product_BOM_ID());
|
||||
production.saveEx();
|
||||
|
||||
int productionCreate = 53226;
|
||||
MProcess process = MProcess.get(Env.getCtx(), productionCreate);
|
||||
ProcessInfo pi = new ProcessInfo(process.getName(), process.get_ID());
|
||||
pi.setAD_Client_ID(getAD_Client_ID());
|
||||
pi.setAD_User_ID(getAD_User_ID());
|
||||
pi.setRecord_ID(production.get_ID());
|
||||
pi.setTransactionName(getTrxName());
|
||||
ServerProcessCtl.process(pi, getTrx(), false);
|
||||
assertFalse(pi.isError(), pi.getSummary());
|
||||
|
||||
production.load(getTrxName());
|
||||
assertEquals("Y", production.getIsCreated(), "MProduction.IsCreated != Y");
|
||||
assertTrue(production.getLines().length > 0, "No Production Lines");
|
||||
|
||||
ProcessInfo info = MWorkflow.runDocumentActionWorkflow(production, DocAction.ACTION_Complete);
|
||||
production.load(getTrxName());
|
||||
assertFalse(info.isError(), info.getSummary());
|
||||
assertEquals(DocAction.STATUS_Completed, production.getDocStatus(), "Production Status="+production.getDocStatus());
|
||||
|
||||
BigDecimal componentOnHand2 = MStorageOnHand.getQtyOnHand(mulchId, getM_Warehouse_ID(), 0, getTrxName());
|
||||
BigDecimal endProductOnHand2 = MStorageOnHand.getQtyOnHand(mulchX.get_ID(), getM_Warehouse_ID(), 0, getTrxName());
|
||||
|
||||
BigDecimal componentChange = componentOnHand2.subtract(componentOnHand1).setScale(0);
|
||||
BigDecimal endProductChange = endProductOnHand2.subtract(endProductOnHand1).setScale(0);
|
||||
assertEquals(new BigDecimal("-1"), componentChange, "On hand of component doesn't reduce as expected");
|
||||
assertEquals(new BigDecimal("1"), endProductChange, "On hand of end product doesn't increase as expected");
|
||||
|
||||
if (!production.isPosted()) {
|
||||
String msg = DocumentEngine.postImmediate(Env.getCtx(), getAD_Client_ID(), MProduction.Table_ID, production.get_ID(), false, getTrxName());
|
||||
assertNull(msg, msg);
|
||||
}
|
||||
|
||||
BigDecimal endProductCost = MCost.getCurrentCost(mulchX, 0, getTrxName());
|
||||
MAcctSchema as = MClient.get(getAD_Client_ID()).getAcctSchema();
|
||||
componentCost = componentCost.setScale(as.getCostingPrecision(), RoundingMode.HALF_UP);
|
||||
endProductCost = endProductCost.setScale(as.getCostingPrecision(), RoundingMode.HALF_UP);
|
||||
assertEquals(componentCost, endProductCost, "Cost not roll up correctly");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStandardCostingProduction() {
|
||||
MProductCategory category = new MProductCategory(Env.getCtx(), 0, null);
|
||||
category.setName("Standard Costing");
|
||||
category.saveEx();
|
||||
|
||||
String whereClause = "M_Product_Category_ID=?";
|
||||
List<MProductCategoryAcct> categoryAccts = new Query(Env.getCtx(), MProductCategoryAcct.Table_Name, whereClause, null)
|
||||
.setParameters(category.get_ID())
|
||||
.list();
|
||||
for (MProductCategoryAcct categoryAcct : categoryAccts) {
|
||||
categoryAcct.setCostingMethod(MAcctSchema.COSTINGMETHOD_StandardCosting);
|
||||
categoryAcct.saveEx();
|
||||
}
|
||||
// ProductCost api doesn't use trx to retrieve product
|
||||
int mulchId = 137;
|
||||
MProduct mulch = new MProduct(Env.getCtx(), mulchId, null);
|
||||
int categorySaveId = mulch.getM_Product_Category_ID();
|
||||
mulch.setM_Product_Category_ID(category.get_ID());
|
||||
mulch.saveEx();
|
||||
|
||||
try {
|
||||
int hqLocator = 101;
|
||||
createPOAndMRForProduct(mulchId);
|
||||
|
||||
BigDecimal componentOnHand1 = MStorageOnHand.getQtyOnHand(mulchId, getM_Warehouse_ID(), 0, getTrxName());
|
||||
BigDecimal componentCost = MCost.getCurrentCost(mulch, 0, getTrxName());
|
||||
|
||||
MProduct mulchX = new MProduct(Env.getCtx(), 0, getTrxName());
|
||||
mulchX.setName("Mulch X");
|
||||
mulchX.setIsBOM(true);
|
||||
mulchX.setIsStocked(true);
|
||||
mulchX.setC_UOM_ID(mulch.getC_UOM_ID());
|
||||
mulchX.setM_Product_Category_ID(category.getM_Product_Category_ID());
|
||||
mulchX.setProductType(mulch.getProductType());
|
||||
mulchX.setM_AttributeSet_ID(mulch.getM_AttributeSet_ID());
|
||||
mulchX.setC_TaxCategory_ID(mulch.getC_TaxCategory_ID());
|
||||
mulchX.saveEx();
|
||||
BigDecimal endProductOnHand1 = MStorageOnHand.getQtyOnHand(mulchX.get_ID(), getM_Warehouse_ID(), 0, getTrxName());
|
||||
|
||||
int costAdjustmentDocTypeId = 200004;
|
||||
MInventory inventory = new MInventory(Env.getCtx(), 0, getTrxName());
|
||||
inventory.setCostingMethod(MAcctSchema.COSTINGMETHOD_StandardCosting);
|
||||
inventory.setC_DocType_ID(costAdjustmentDocTypeId);
|
||||
inventory.setM_Warehouse_ID(getM_Warehouse_ID());
|
||||
inventory.setMovementDate(getLoginDate());
|
||||
inventory.setDocAction(DocAction.ACTION_Complete);
|
||||
inventory.saveEx();
|
||||
|
||||
MAcctSchema as = MClient.get(getAD_Client_ID()).getAcctSchema();
|
||||
BigDecimal endProductCost = new BigDecimal("2.50").setScale(as.getCostingPrecision(), RoundingMode.HALF_UP);
|
||||
MInventoryLine il = new MInventoryLine(Env.getCtx(), 0, getTrxName());
|
||||
il.setM_Inventory_ID(inventory.get_ID());
|
||||
il.setM_Locator_ID(hqLocator);
|
||||
il.setM_Product_ID(mulchX.getM_Product_ID());
|
||||
il.setCurrentCostPrice(new BigDecimal("0"));
|
||||
il.setNewCostPrice(endProductCost);
|
||||
il.saveEx();
|
||||
|
||||
ProcessInfo info = MWorkflow.runDocumentActionWorkflow(inventory, DocAction.ACTION_Complete);
|
||||
inventory.load(getTrxName());
|
||||
assertFalse(info.isError(), info.getSummary());
|
||||
assertEquals(DocAction.STATUS_Completed, inventory.getDocStatus(), "Cost Adjustment Status="+inventory.getDocStatus());
|
||||
|
||||
if (!inventory.isPosted()) {
|
||||
String msg = DocumentEngine.postImmediate(Env.getCtx(), getAD_Client_ID(), MInventory.Table_ID, inventory.get_ID(), false, getTrxName());
|
||||
assertNull(msg, msg);
|
||||
}
|
||||
BigDecimal adjusted = MCost.getCurrentCost(mulchX, 0, getTrxName()).setScale(as.getCostingPrecision(), RoundingMode.HALF_UP);
|
||||
assertEquals(endProductCost, adjusted, "Cost not adjusted: " + adjusted.toPlainString());
|
||||
|
||||
MPPProductBOM bom = new MPPProductBOM(Env.getCtx(), 0, getTrxName());
|
||||
bom.setM_Product_ID(mulchX.get_ID());
|
||||
bom.setBOMType(MPPProductBOM.BOMTYPE_CurrentActive);
|
||||
bom.setBOMUse(MPPProductBOM.BOMUSE_Master);
|
||||
bom.setName(mulchX.getName());
|
||||
bom.saveEx();
|
||||
|
||||
MPPProductBOMLine line = new MPPProductBOMLine(bom);
|
||||
line.setM_Product_ID(mulchId);
|
||||
line.setQtyBOM(new BigDecimal("1"));
|
||||
line.saveEx();
|
||||
|
||||
mulchX.load(getTrxName());
|
||||
mulchX.setIsVerified(true);
|
||||
mulchX.saveEx();
|
||||
|
||||
MProduction production = new MProduction(Env.getCtx(), 0, getTrxName());
|
||||
production.setM_Product_ID(mulchX.get_ID());
|
||||
production.setM_Locator_ID(hqLocator);
|
||||
production.setIsUseProductionPlan(false);
|
||||
production.setMovementDate(getLoginDate());
|
||||
production.setDocAction(DocAction.ACTION_Complete);
|
||||
production.setDocStatus(DocAction.STATUS_Drafted);
|
||||
production.setIsComplete(false);
|
||||
production.setProductionQty(new BigDecimal("1"));
|
||||
production.setPP_Product_BOM_ID(bom.getPP_Product_BOM_ID());
|
||||
production.saveEx();
|
||||
|
||||
int productionCreate = 53226;
|
||||
MProcess process = MProcess.get(Env.getCtx(), productionCreate);
|
||||
ProcessInfo pi = new ProcessInfo(process.getName(), process.get_ID());
|
||||
pi.setAD_Client_ID(getAD_Client_ID());
|
||||
pi.setAD_User_ID(getAD_User_ID());
|
||||
pi.setRecord_ID(production.get_ID());
|
||||
pi.setTransactionName(getTrxName());
|
||||
ServerProcessCtl.process(pi, getTrx(), false);
|
||||
assertFalse(pi.isError(), pi.getSummary());
|
||||
|
||||
production.load(getTrxName());
|
||||
assertEquals("Y", production.getIsCreated(), "MProduction.IsCreated != Y");
|
||||
assertTrue(production.getLines().length > 0, "No Production Lines");
|
||||
|
||||
info = MWorkflow.runDocumentActionWorkflow(production, DocAction.ACTION_Complete);
|
||||
production.load(getTrxName());
|
||||
assertFalse(info.isError(), info.getSummary());
|
||||
assertEquals(DocAction.STATUS_Completed, production.getDocStatus(), "Production Status="+production.getDocStatus());
|
||||
|
||||
BigDecimal componentOnHand2 = MStorageOnHand.getQtyOnHand(mulchId, getM_Warehouse_ID(), 0, getTrxName());
|
||||
BigDecimal endProductOnHand2 = MStorageOnHand.getQtyOnHand(mulchX.get_ID(), getM_Warehouse_ID(), 0, getTrxName());
|
||||
BigDecimal componentChange = componentOnHand2.subtract(componentOnHand1).setScale(0);
|
||||
BigDecimal endProductChange = endProductOnHand2.subtract(endProductOnHand1).setScale(0);
|
||||
|
||||
assertEquals(componentChange, new BigDecimal("-1"), "On hand of component doesn't reduce as expected");
|
||||
assertEquals(endProductChange, new BigDecimal("1"), "On hand of end product doesn't increase as expected");
|
||||
|
||||
if (!production.isPosted()) {
|
||||
String msg = DocumentEngine.postImmediate(Env.getCtx(), getAD_Client_ID(), MProduction.Table_ID, production.get_ID(), false, getTrxName());
|
||||
assertNull(msg, msg);
|
||||
}
|
||||
|
||||
BigDecimal endProductCost1 = MCost.getCurrentCost(mulchX, 0, getTrxName()).setScale(as.getCostingPrecision(), RoundingMode.HALF_UP);
|
||||
assertEquals(endProductCost, endProductCost1, "Standard Cost Changed");
|
||||
|
||||
ProductCost pc = new ProductCost (Env.getCtx(), mulchX.getM_Product_ID(), 0, getTrxName());
|
||||
MAccount acctVariance = pc.getAccount(ProductCost.ACCTTYPE_P_RateVariance, as);
|
||||
|
||||
whereClause = MFactAcct.COLUMNNAME_AD_Table_ID + "=" + MProduction.Table_ID
|
||||
+ " AND " + MFactAcct.COLUMNNAME_Record_ID + "=" + production.get_ID()
|
||||
+ " AND " + MFactAcct.COLUMNNAME_C_AcctSchema_ID + "=" + as.getC_AcctSchema_ID()
|
||||
+ " AND " + MFactAcct.COLUMNNAME_Account_ID + "=" + acctVariance.getAccount_ID();
|
||||
int[] ids = MFactAcct.getAllIDs(MFactAcct.Table_Name, whereClause, getTrxName());
|
||||
BigDecimal variance = BigDecimal.ZERO;
|
||||
for (int id : ids) {
|
||||
MFactAcct fa = new MFactAcct(Env.getCtx(), id, getTrxName());
|
||||
variance = fa.getAmtAcctDr().subtract(fa.getAmtAcctCr());
|
||||
break;
|
||||
}
|
||||
BigDecimal varianceExpected = componentCost.subtract(endProductCost).setScale(as.getStdPrecision(), RoundingMode.HALF_UP);
|
||||
assertEquals(varianceExpected.setScale(2, RoundingMode.HALF_UP), variance.setScale(2, RoundingMode.HALF_UP), "Variance not posted correctly.");
|
||||
} finally {
|
||||
getTrx().rollback();
|
||||
mulch.setM_Product_Category_ID(categorySaveId);
|
||||
mulch.saveEx();
|
||||
category.deleteEx(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRollUp() {
|
||||
MProductCategory category = new MProductCategory(Env.getCtx(), 0, null);
|
||||
category.setName("Standard Costing");
|
||||
category.saveEx();
|
||||
|
||||
String whereClause = "M_Product_Category_ID=?";
|
||||
List<MProductCategoryAcct> categoryAccts = new Query(Env.getCtx(), MProductCategoryAcct.Table_Name, whereClause, null)
|
||||
.setParameters(category.get_ID())
|
||||
.list();
|
||||
for (MProductCategoryAcct categoryAcct : categoryAccts) {
|
||||
categoryAcct.setCostingMethod(MAcctSchema.COSTINGMETHOD_StandardCosting);
|
||||
categoryAcct.saveEx();
|
||||
}
|
||||
|
||||
try {
|
||||
int rollUpProcessId = 53230;
|
||||
int mulchId = 137;
|
||||
MProduct mulch = new MProduct(Env.getCtx(), mulchId, getTrxName());
|
||||
mulch.setM_Product_Category_ID(category.get_ID());
|
||||
mulch.saveEx();
|
||||
|
||||
MAcctSchema as = MClient.get(getAD_Client_ID()).getAcctSchema();
|
||||
BigDecimal componentCost = MCost.getCurrentCost(mulch, 0, getTrxName()).setScale(as.getCostingPrecision(), RoundingMode.HALF_UP);
|
||||
|
||||
MProduct mulchX = new MProduct(Env.getCtx(), 0, getTrxName());
|
||||
mulchX.setName("Mulch X");
|
||||
mulchX.setIsBOM(true);
|
||||
mulchX.setIsStocked(true);
|
||||
mulchX.setC_UOM_ID(mulch.getC_UOM_ID());
|
||||
mulchX.setM_Product_Category_ID(category.getM_Product_Category_ID());
|
||||
mulchX.setProductType(mulch.getProductType());
|
||||
mulchX.setM_AttributeSet_ID(mulch.getM_AttributeSet_ID());
|
||||
mulchX.setC_TaxCategory_ID(mulch.getC_TaxCategory_ID());
|
||||
mulchX.saveEx();
|
||||
|
||||
MPPProductBOM bom = new MPPProductBOM(Env.getCtx(), 0, getTrxName());
|
||||
bom.setM_Product_ID(mulchX.get_ID());
|
||||
bom.setBOMType(MPPProductBOM.BOMTYPE_CurrentActive);
|
||||
bom.setBOMUse(MPPProductBOM.BOMUSE_Master);
|
||||
bom.setName(mulchX.getName());
|
||||
bom.saveEx();
|
||||
|
||||
MPPProductBOMLine line = new MPPProductBOMLine(bom);
|
||||
line.setM_Product_ID(mulchId);
|
||||
line.setQtyBOM(new BigDecimal("1"));
|
||||
line.saveEx();
|
||||
|
||||
mulchX.load(getTrxName());
|
||||
mulchX.setIsVerified(true);
|
||||
mulchX.saveEx();
|
||||
|
||||
MPInstance instance = new MPInstance(Env.getCtx(), rollUpProcessId, 0);
|
||||
instance.saveEx();
|
||||
MPInstancePara para = new MPInstancePara(instance, 10);
|
||||
para.setParameterName("M_Product_ID");
|
||||
para.setP_Number(mulchX.get_ID());
|
||||
para.saveEx();
|
||||
|
||||
para = new MPInstancePara(instance, 20);
|
||||
para.setParameterName("M_CostElement_ID");
|
||||
para.setP_Number(MCostElement.getMaterialCostElement(Env.getCtx(), MAcctSchema.COSTINGMETHOD_StandardCosting).get_ID());
|
||||
para.saveEx();
|
||||
|
||||
ProcessInfo info = new ProcessInfo(MProcess.get(rollUpProcessId).getName(), rollUpProcessId);
|
||||
info.setAD_PInstance_ID(instance.getAD_PInstance_ID());
|
||||
info.setTransactionName(getTrxName());
|
||||
ServerProcessCtl.process(info, getTrx(), false);
|
||||
assertFalse(info.isError(), info.getSummary());
|
||||
|
||||
BigDecimal endProductCost = MCost.getCurrentCost(mulchX, 0, getTrxName()).setScale(as.getCostingPrecision(), RoundingMode.HALF_UP);;
|
||||
assertEquals(componentCost, endProductCost, "BOM Cost not roll up.");
|
||||
} finally {
|
||||
getTrx().rollback();
|
||||
category.deleteEx(true);
|
||||
}
|
||||
}
|
||||
|
||||
// creates an order and material receipt for qty 25 at special price of 2.60 each
|
||||
private void createPOAndMRForProduct(int mulchId) {
|
||||
MOrder order = new MOrder(Env.getCtx(), 0, getTrxName());
|
||||
order.setBPartner(MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.PATIO.id));
|
||||
order.setC_DocTypeTarget_ID(DictionaryIDs.C_DocType.PURCHASE_ORDER.id);
|
||||
order.setIsSOTrx(false);
|
||||
order.setSalesRep_ID(DictionaryIDs.AD_User.GARDEN_ADMIN.id);
|
||||
order.setDocStatus(DocAction.STATUS_Drafted);
|
||||
order.setDocAction(DocAction.ACTION_Complete);
|
||||
Timestamp today = TimeUtil.getDay(System.currentTimeMillis());
|
||||
order.setDateOrdered(today);
|
||||
order.setDatePromised(today);
|
||||
order.saveEx();
|
||||
|
||||
MOrderLine line1 = new MOrderLine(order);
|
||||
line1.setLine(10);
|
||||
line1.setProduct(MProduct.get(Env.getCtx(), mulchId));
|
||||
line1.setQty(new BigDecimal("25"));
|
||||
line1.setPrice(new BigDecimal("2.60"));
|
||||
line1.setDatePromised(today);
|
||||
line1.saveEx();
|
||||
|
||||
ProcessInfo info = MWorkflow.runDocumentActionWorkflow(order, DocAction.ACTION_Complete);
|
||||
assertFalse(info.isError(), info.getSummary());
|
||||
order.load(getTrxName());
|
||||
assertEquals(DocAction.STATUS_Completed, order.getDocStatus());
|
||||
|
||||
MInOut receipt1 = new MInOut(order, DictionaryIDs.C_DocType.MM_RECEIPT.id, order.getDateOrdered());
|
||||
receipt1.setDocStatus(DocAction.STATUS_Drafted);
|
||||
receipt1.setDocAction(DocAction.ACTION_Complete);
|
||||
receipt1.saveEx();
|
||||
|
||||
MInOutLine receiptLine1 = new MInOutLine(receipt1);
|
||||
receiptLine1.setOrderLine(line1, 0, new BigDecimal("25"));
|
||||
receiptLine1.setQty(new BigDecimal("25"));
|
||||
receiptLine1.saveEx();
|
||||
|
||||
info = MWorkflow.runDocumentActionWorkflow(receipt1, DocAction.ACTION_Complete);
|
||||
assertFalse(info.isError(), info.getSummary());
|
||||
receipt1.load(getTrxName());
|
||||
assertEquals(DocAction.STATUS_Completed, receipt1.getDocStatus());
|
||||
if (!receipt1.isPosted()) {
|
||||
String error = DocumentEngine.postImmediate(Env.getCtx(), receipt1.getAD_Client_ID(), receipt1.get_Table_ID(), receipt1.get_ID(), false, getTrxName());
|
||||
assertNull(error, error);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -219,7 +219,7 @@ public class PurchaseOrderTest extends AbstractTestCase {
|
|||
Properties ctx = Env.getCtx();
|
||||
String trxName = getTrxName();
|
||||
|
||||
BigDecimal qtyOrderedOriginal = getQtyOrdered(ctx, DictionaryIDs.M_Product.MULCH.id, trxName);
|
||||
BigDecimal qtyOrderedOriginal = getQtyOrdered(ctx, DictionaryIDs.M_Product.HOLLY_BUSH.id, trxName);
|
||||
|
||||
MOrder order = new MOrder(ctx, 0, trxName);
|
||||
order.setBPartner(MBPartner.get(ctx, DictionaryIDs.C_BPartner.PATIO.id));
|
||||
|
@ -235,7 +235,7 @@ public class PurchaseOrderTest extends AbstractTestCase {
|
|||
|
||||
MOrderLine line1 = new MOrderLine(order);
|
||||
line1.setLine(10);
|
||||
line1.setProduct(MProduct.get(ctx, DictionaryIDs.M_Product.MULCH.id));
|
||||
line1.setProduct(MProduct.get(ctx, DictionaryIDs.M_Product.HOLLY_BUSH.id));
|
||||
line1.setQty(THREE);
|
||||
line1.setDatePromised(today);
|
||||
line1.saveEx();
|
||||
|
@ -247,7 +247,7 @@ public class PurchaseOrderTest extends AbstractTestCase {
|
|||
line1.load(trxName);
|
||||
assertEquals(0, line1.getQtyReserved().compareTo(THREE));
|
||||
|
||||
BigDecimal newQtyOrdered = getQtyOrdered(ctx, DictionaryIDs.M_Product.MULCH.id, trxName);
|
||||
BigDecimal newQtyOrdered = getQtyOrdered(ctx, DictionaryIDs.M_Product.HOLLY_BUSH.id, trxName);
|
||||
assertEquals(0, qtyOrderedOriginal.add(THREE).compareTo(newQtyOrdered));
|
||||
|
||||
MInOut receipt1 = new MInOut(order, DictionaryIDs.C_DocType.MM_RECEIPT.id, order.getDateOrdered());
|
||||
|
@ -268,7 +268,7 @@ public class PurchaseOrderTest extends AbstractTestCase {
|
|||
line1.load(trxName);
|
||||
assertEquals(0, line1.getQtyReserved().compareTo(Env.ZERO));
|
||||
|
||||
newQtyOrdered = getQtyOrdered(ctx, DictionaryIDs.M_Product.MULCH.id, trxName);
|
||||
newQtyOrdered = getQtyOrdered(ctx, DictionaryIDs.M_Product.HOLLY_BUSH.id, trxName);
|
||||
assertEquals(0, qtyOrderedOriginal.compareTo(newQtyOrdered));
|
||||
|
||||
// reactivate the purchase order
|
||||
|
@ -291,7 +291,7 @@ public class PurchaseOrderTest extends AbstractTestCase {
|
|||
// IDEMPIERE-5039 - when reservations go negative they are changed to zero
|
||||
assertEquals(0, line1.getQtyReserved().compareTo(Env.ZERO));
|
||||
|
||||
newQtyOrdered = getQtyOrdered(ctx, DictionaryIDs.M_Product.MULCH.id, trxName);
|
||||
newQtyOrdered = getQtyOrdered(ctx, DictionaryIDs.M_Product.HOLLY_BUSH.id, trxName);
|
||||
assertEquals(0, qtyOrderedOriginal.compareTo(newQtyOrdered));
|
||||
|
||||
// create a new material receipt for the -3 reversed
|
||||
|
@ -313,7 +313,7 @@ public class PurchaseOrderTest extends AbstractTestCase {
|
|||
line1.load(trxName);
|
||||
assertEquals(0, line1.getQtyReserved().compareTo(Env.ZERO));
|
||||
|
||||
newQtyOrdered = getQtyOrdered(ctx, DictionaryIDs.M_Product.MULCH.id, trxName);
|
||||
newQtyOrdered = getQtyOrdered(ctx, DictionaryIDs.M_Product.HOLLY_BUSH.id, trxName);
|
||||
assertEquals(0, qtyOrderedOriginal.compareTo(newQtyOrdered));
|
||||
}
|
||||
|
||||
|
@ -490,7 +490,7 @@ public class PurchaseOrderTest extends AbstractTestCase {
|
|||
new Object[] {MSysConfig.VALIDATE_MATCHING_TO_ORDERED_QTY}, null);
|
||||
CacheMgt.get().reset();
|
||||
|
||||
BigDecimal initialQtyOrdered = getQtyOrdered(Env.getCtx(), DictionaryIDs.M_Product.MULCH.id, getTrxName());
|
||||
BigDecimal initialQtyOrdered = getQtyOrdered(Env.getCtx(), DictionaryIDs.M_Product.ROSE_BUSH.id, getTrxName());
|
||||
try {
|
||||
MOrder order = new MOrder(ctx, 0, trxName);
|
||||
order.setBPartner(MBPartner.get(ctx, DictionaryIDs.C_BPartner.PATIO.id));
|
||||
|
@ -506,7 +506,7 @@ public class PurchaseOrderTest extends AbstractTestCase {
|
|||
|
||||
MOrderLine line1 = new MOrderLine(order);
|
||||
line1.setLine(10);
|
||||
line1.setProduct(MProduct.get(ctx, DictionaryIDs.M_Product.MULCH.id));
|
||||
line1.setProduct(MProduct.get(ctx, DictionaryIDs.M_Product.ROSE_BUSH.id));
|
||||
line1.setQty(new BigDecimal("1"));
|
||||
line1.setDatePromised(today);
|
||||
line1.saveEx();
|
||||
|
@ -517,7 +517,7 @@ public class PurchaseOrderTest extends AbstractTestCase {
|
|||
assertEquals(DocAction.STATUS_Completed, order.getDocStatus(), "Order not completed");
|
||||
line1.load(trxName);
|
||||
assertEquals(1, line1.getQtyReserved().intValue(), "Wrong Order line qty reserved value");
|
||||
BigDecimal newQtyOrdered = getQtyOrdered(Env.getCtx(), DictionaryIDs.M_Product.MULCH.id, getTrxName());
|
||||
BigDecimal newQtyOrdered = getQtyOrdered(Env.getCtx(), DictionaryIDs.M_Product.ROSE_BUSH.id, getTrxName());
|
||||
assertEquals(initialQtyOrdered.intValue()+1, newQtyOrdered.intValue(), "Quantiy Ordered not updated as expected");
|
||||
|
||||
MInOut receipt1 = new MInOut(order, DictionaryIDs.C_DocType.MM_RECEIPT.id, order.getDateOrdered());
|
||||
|
@ -537,7 +537,7 @@ public class PurchaseOrderTest extends AbstractTestCase {
|
|||
|
||||
line1.load(trxName);
|
||||
assertEquals(0, line1.getQtyReserved().intValue(), "Wrong order line qty reserved value");
|
||||
newQtyOrdered = getQtyOrdered(Env.getCtx(), DictionaryIDs.M_Product.MULCH.id, getTrxName());
|
||||
newQtyOrdered = getQtyOrdered(Env.getCtx(), DictionaryIDs.M_Product.ROSE_BUSH.id, getTrxName());
|
||||
assertEquals(initialQtyOrdered.intValue(), newQtyOrdered.intValue(), "Quantiy Ordered not updated as expected");
|
||||
|
||||
// reactivate the purchase order
|
||||
|
@ -559,7 +559,7 @@ public class PurchaseOrderTest extends AbstractTestCase {
|
|||
line1.load(trxName);
|
||||
assertEquals(0, line1.getQtyReserved().intValue(), "Wrong order line qty reserved value");
|
||||
assertEquals(2, line1.getQtyOrdered().intValue(), "Wrong order line qty ordered value");
|
||||
newQtyOrdered = getQtyOrdered(Env.getCtx(), DictionaryIDs.M_Product.MULCH.id, getTrxName());
|
||||
newQtyOrdered = getQtyOrdered(Env.getCtx(), DictionaryIDs.M_Product.ROSE_BUSH.id, getTrxName());
|
||||
assertEquals(initialQtyOrdered.intValue(), newQtyOrdered.intValue(), "Quantiy Ordered not updated as expected");
|
||||
|
||||
//reverse MR
|
||||
|
@ -574,7 +574,7 @@ public class PurchaseOrderTest extends AbstractTestCase {
|
|||
line1.load(trxName);
|
||||
assertEquals(2, line1.getQtyReserved().intValue(), "Wrong order line qty reserved value");
|
||||
assertEquals(0, line1.getQtyDelivered().intValue(), "Wrong order line qty delivered value");
|
||||
newQtyOrdered = getQtyOrdered(Env.getCtx(), DictionaryIDs.M_Product.MULCH.id, getTrxName());
|
||||
newQtyOrdered = getQtyOrdered(Env.getCtx(), DictionaryIDs.M_Product.ROSE_BUSH.id, getTrxName());
|
||||
assertEquals(initialQtyOrdered.intValue()+2, newQtyOrdered.intValue(), "Quantiy Ordered not updated as expected");
|
||||
} finally {
|
||||
DB.executeUpdateEx("UPDATE AD_SysConfig SET Value='Y' WHERE AD_Client_ID=0 AND Name=?",
|
||||
|
@ -599,7 +599,7 @@ public class PurchaseOrderTest extends AbstractTestCase {
|
|||
|
||||
MOrderLine line1 = new MOrderLine(order);
|
||||
line1.setLine(10);
|
||||
line1.setProduct(MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.MULCH.id));
|
||||
line1.setProduct(MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.ROSE_BUSH.id));
|
||||
line1.setQty(new BigDecimal("1"));
|
||||
line1.setDatePromised(today);
|
||||
line1.saveEx();
|
||||
|
|
|
@ -69,10 +69,12 @@ import org.compiere.wf.MWorkflow;
|
|||
import org.idempiere.test.AbstractTestCase;
|
||||
import org.idempiere.test.DictionaryIDs;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.parallel.Isolated;
|
||||
|
||||
/**
|
||||
* @author hengsin
|
||||
*/
|
||||
@Isolated
|
||||
public class SalesOrderTest extends AbstractTestCase {
|
||||
|
||||
public SalesOrderTest() {
|
||||
|
|
|
@ -120,12 +120,14 @@ import org.idempiere.fa.service.api.IDepreciationMethodFactory;
|
|||
import org.idempiere.test.AbstractTestCase;
|
||||
import org.idempiere.test.TestActivator;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.parallel.Isolated;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hengsin
|
||||
*
|
||||
*/
|
||||
@Isolated
|
||||
public class CacheTest extends AbstractTestCase {
|
||||
|
||||
private static final int ORDER_HEADER_PRINT_FORMAT_ID = 118;
|
||||
|
|
Loading…
Reference in New Issue