You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by nm...@apache.org on 2018/12/27 14:40:03 UTC
svn commit: r1849800 - in /ofbiz/ofbiz-framework/trunk/applications/order:
./ config/ groovyScripts/quote/ groovyScripts/test/ minilang/quote/
minilang/test/ servicedef/ testdef/ testdef/data/ widget/ordermgr/
Author: nmalin
Date: Thu Dec 27 14:40:03 2018
New Revision: 1849800
URL: http://svn.apache.org/viewvc?rev=1849800&view=rev
Log:
Improved: Convert QuoteServices.xml mini lang to groovy - Deprecate Mini Lang
(OFBIZ-10553) (OFBIZ-9350)
Convert all QuoteServices.xml and their xml test
Thanks to Antoine Ouvrard, Leila Mekika, Gil Portenseigne and Mathieu Lirzin for this team work to convert all function and tests case
Added:
ofbiz/ofbiz-framework/trunk/applications/order/groovyScripts/test/
ofbiz/ofbiz-framework/trunk/applications/order/groovyScripts/test/QuoteTests.groovy (with props)
ofbiz/ofbiz-framework/trunk/applications/order/testdef/QuoteTests.xml
- copied, changed from r1849799, ofbiz/ofbiz-framework/trunk/applications/order/testdef/quotetests.xml
Removed:
ofbiz/ofbiz-framework/trunk/applications/order/minilang/quote/QuoteServices.xml
ofbiz/ofbiz-framework/trunk/applications/order/minilang/test/QuoteTests.xml
ofbiz/ofbiz-framework/trunk/applications/order/testdef/quotetests.xml
Modified:
ofbiz/ofbiz-framework/trunk/applications/order/config/OrderErrorUiLabels.xml
ofbiz/ofbiz-framework/trunk/applications/order/config/OrderUiLabels.xml
ofbiz/ofbiz-framework/trunk/applications/order/groovyScripts/quote/QuoteServices.groovy
ofbiz/ofbiz-framework/trunk/applications/order/ofbiz-component.xml
ofbiz/ofbiz-framework/trunk/applications/order/servicedef/services_quote.xml
ofbiz/ofbiz-framework/trunk/applications/order/testdef/data/QuoteTestData.xml
ofbiz/ofbiz-framework/trunk/applications/order/widget/ordermgr/QuoteWorkEffortForms.xml
Modified: ofbiz/ofbiz-framework/trunk/applications/order/config/OrderErrorUiLabels.xml
URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/order/config/OrderErrorUiLabels.xml?rev=1849800&r1=1849799&r2=1849800&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/order/config/OrderErrorUiLabels.xml (original)
+++ ofbiz/ofbiz-framework/trunk/applications/order/config/OrderErrorUiLabels.xml Thu Dec 27 14:40:03 2018
@@ -3181,6 +3181,14 @@
<value xml:lang="zh">å¿«éæ·»å 订åæç»</value>
<value xml:lang="zh-TW">å¿«éæ·»å è¨å®æç´°</value>
</property>
+ <property key="OrderQuoteGetNextIdError">
+ <value xml:lang="en">Error during id creation</value>
+ <value xml:lang="fr">Erreur durant la création de l'ID.</value>
+ </property>
+ <property key="OrderQuoteIdAlreadyExists">
+ <value xml:lang="en">ERROR: Quote with ID ${quoteId} already exists</value>
+ <value xml:lang="fr">ERREUR : Un devis avec la référence ${quoteId} existe déjà .</value>
+ </property>
<property key="OrderQuotePercent">
<value xml:lang="ar">Ùسبة عرض اÙسعر</value>
<value xml:lang="de">Angebotsprozente</value>
Modified: ofbiz/ofbiz-framework/trunk/applications/order/config/OrderUiLabels.xml
URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/order/config/OrderUiLabels.xml?rev=1849800&r1=1849799&r2=1849800&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/order/config/OrderUiLabels.xml (original)
+++ ofbiz/ofbiz-framework/trunk/applications/order/config/OrderUiLabels.xml Thu Dec 27 14:40:03 2018
@@ -9014,6 +9014,7 @@
</property>
<property key="OrderOrderQuoteUpdatedSuccessfully">
<value xml:lang="en">Quote updated successfully.</value>
+ <value xml:lang="fr">Le devis a été mis à jour avec succès.</value>
</property>
<property key="OrderOrderQuoteViewProfit">
<value xml:lang="ar">Ù
شاÙدة ربØÙØ© عرض اÙسعر</value>
Modified: ofbiz/ofbiz-framework/trunk/applications/order/groovyScripts/quote/QuoteServices.groovy
URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/order/groovyScripts/quote/QuoteServices.groovy?rev=1849800&r1=1849799&r2=1849800&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/order/groovyScripts/quote/QuoteServices.groovy (original)
+++ ofbiz/ofbiz-framework/trunk/applications/order/groovyScripts/quote/QuoteServices.groovy Thu Dec 27 14:40:03 2018
@@ -17,13 +17,286 @@
* under the License.
*/
-
+import org.apache.ofbiz.base.util.Debug
+import org.apache.ofbiz.base.util.UtilValidate
+import org.apache.ofbiz.base.util.UtilProperties
+import org.apache.ofbiz.base.util.UtilDateTime
+import org.apache.ofbiz.entity.GenericValue
+import org.apache.ofbiz.entity.condition.EntityCondition
+import org.apache.ofbiz.entity.condition.EntityOperator
+import org.apache.ofbiz.order.shoppingcart.ShoppingCart
+import org.apache.ofbiz.order.shoppingcart.ShoppingCartItem
+import org.apache.ofbiz.product.config.ProductConfigWorker
+import org.apache.ofbiz.product.config.ProductConfigWrapper
import org.apache.ofbiz.service.ExecutionServiceException
+import org.apache.ofbiz.service.ModelService
import org.apache.ofbiz.service.ServiceUtil
+String module = 'QuoteServices.groovy'
+
+/**
+ * Set the Quote status to ordered.
+ */
+def checkUpdateQuoteStatus() {
+ GenericValue quote = from('Quote').where(parameters).queryOne()
+ if (!quote) {
+ return error(UtilProperties.getMessage('OrderErrorUiLabels', 'OrderQuoteDoesNotExists', locale))
+ }
+ quote.statusId = 'QUO_ORDERED'
+ quote.store()
+ return success()
+}
+
+/**
+ * Get new Quote sequence Id.
+ */
+def getNextQuoteId() {
+ // Try to find PartyAcctgPreference for parameters.partyId, see if we need any special quote number sequencing
+ GenericValue partyAcctgPreference = from('PartyAcctgPreference').where('partyId', parameters.partyId).queryOne()
+ Debug.logInfo("In getNextQuoteId partyId is [${parameters.partyId}], partyAcctgPreference: ${partyAcctgPreference}",
+ module)
+
+ Map customMethod = null
+ if (partyAcctgPreference) {
+ customMethod = partyAcctgPreference.getRelatedOne('QuoteCustomMethod', false)
+ } else {
+ Debug.logWarning("Acctg preference not defined for partyId [${parameters.partyId}]", module)
+ }
+
+ String customMethodName
+ if (customMethod?.customMethodName) {
+ customMethodName = customMethod.customMethodName
+ } else if (partyAcctgPreference?.oldQuoteSequenceEnumId == 'QTESQ_ENF_SEQ') {
+ // Retrieve service from deprecated enumeration
+ customMethodName = 'quoteSequenceEnforced'
+ }
+
+ String quoteId
+ if (customMethodName) {
+ Map serviceResult = run service: customMethodName, with: [
+ partyId: parameters.partyId,
+ partyAcctgPreference: partyAcctgPreference
+ ]
+ quoteId = serviceResult.quoteId
+ } else {
+ // Default to the default sequencing: QTESQ_STANDARD
+ quoteId = parameters.quoteId
+ if (quoteId) {
+ GenericValue quote = from('Quote').where('quoteId', quoteId).queryOne()
+ if (quote) {
+ // Return alert if ID already exists
+ return error(UtilProperties.getMessage('OrderErrorUiLabels', 'OrderQuoteIdAlreadyExists', [quoteId: quoteId], locale))
+ } else {
+ // Check the provided ID
+ String errorMessage = UtilValidate.checkValidDatabaseId(quoteId)
+ if (errorMessage) {
+ return error(UtilProperties.getMessage('OrderErrorUiLabels', 'OrderQuoteGetNextIdError', locale) + errorMessage)
+ }
+ }
+ } else {
+ quoteId = delegator.getNextSeqId("Quote")
+ }
+ }
+
+ if (partyAcctgPreference) {
+ quoteId = "${partyAcctgPreference.quoteIdPrefix}${quoteId}"
+ }
+ return [successMessage: null, quoteId: quoteId]
+}
+
+/**
+ * Enforced Sequence (no gaps, per organization).
+ */
+def quoteSequenceEnforced() {
+ Debug.logInfo('In getNextQuoteId sequence enum Enforced', module)
+ GenericValue partyAcctgPreference = parameters.partyAcctgPreference
+ // This is sequential sequencing, we can't skip a number, also it must be a unique sequence per partyIdFrom
+
+ partyAcctgPreference.lastQuoteNumber = partyAcctgPreference.lastQuoteNumber ? partyAcctgPreference.lastQuoteNumber + 1: new Long('1')
+
+ partyAcctgPreference.store()
+ return [successMessage: null, quoteId: partyAcctgPreference.lastQuoteNumber]
+}
+
/**
- * Ensures that a workEffort exist and create a QuoteWorkEffort.
+ * Create a new Quote.
*/
+def createQuote() {
+ if (parameters.partyId
+ && parameters.partyId != userLogin.partyId
+ && !security.hasEntityPermission('ORDERMGR', '_CREATE', userLogin)) {
+ return error(UtilProperties.getMessage('OrderErrorUiLabels', 'OrderSecurityErrorToRunCreateQuote', locale))
+ }
+
+ // Create new entity and create all the fields.
+ GenericValue newEntity = makeValue('Quote', parameters)
+ newEntity.statusId = parameters.statusId ?: 'QUO_CREATED'
+
+ // Create a non existing ID; if we have a productStoreId do it for the payToPartyId of that ProductStore
+ // according to PartyAcctgPreferences, otherwise get from standard sequence.
+ GenericValue productStore
+ if (parameters.productStoreId) {
+ productStore = from('ProductStore').where('productStoreId', parameters.productStoreId).queryOne()
+ }
+ if (productStore?.payToPartyId) {
+ Map serviceResult = run service: 'getNextQuoteId', with: [partyId: productStore.payToPartyId]
+ newEntity.quoteId = serviceResult.quoteId
+ } else {
+ newEntity.quoteId = delegator.getNextSeqId("Quote")
+ }
+
+ // Finally create the record (should not exist already).
+ newEntity.create()
+
+ // If the logged in partyId that is creating the quote is not equal to the partyId
+ // then we associate it to the quote as the request taker.
+ // This is not done if they are the same e.g. a logged in customer that is
+ // creating a quote for its own sake.
+ if (parameters.partyId != userLogin.partyId) {
+ Map serviceResult = run service: 'createQuoteRole', with: [
+ quoteId: newEntity.quoteId,
+ partyId: userLogin.partyId,
+ roleTypeId: 'REQ_TAKER'
+ ]
+ }
+
+ // Set ProductStore's payToPartyId as internal organisation for quote.
+ if (productStore?.payToPartyId) {
+ Map serviceResult = run service: 'createQuoteRole', with: [
+ quoteId: newEntity.quoteId,
+ partyId: productStore.payToPartyId,
+ roleTypeId: 'INTERNAL_ORGANIZATIO'
+ ]
+ }
+ def msg = UtilProperties.getMessage('OrderUiLabels', 'OrderOrderQuoteCreatedSuccessfully', locale)
+ return [successMessage: msg, quoteId: newEntity.quoteId]
+}
+
+/**
+ * Update an existing quote.
+ * @return quoteId
+ */
+def updateQuote() {
+ if (!security.hasEntityPermission('ORDERMGR', '_UPDATE', userLogin)) {
+ return error(UtilProperties.getMessage('OrderErrorUiLabels', 'OrderSecurityErrorToRunUpdateQuote', locale))
+ }
+ quoteId = parameters.quoteId
+ GenericValue quote = from('Quote').where('quoteId', quoteId).queryOne()
+
+ if (!parameters.statusId) {
+ parameters.statusId = quote.statusId
+ }
+
+ if (parameters.statusId != quote.statusId) {
+ // Check if the status change is a valid change.
+ GenericValue validChange = from("StatusValidChange").where('statusId', quote.statusId, 'statusIdTo', parameters.statusId).queryOne()
+
+ if (!validChange) {
+ Debug.logError("The status change from ${quote.statusId} to ${parameters.statusId} is not a valid change", module)
+ // FIXME : LABEL :D
+ return error(UtilProperties.getMessage('OrderErrorUiLabels', 'OrderQuoteStatusChangeIsNotValid', locale))
+ }
+ }
+
+ quote.setNonPKFields(parameters)
+ quote.store()
+
+ return success(UtilProperties.getMessage('OrderUiLabels', 'OrderOrderQuoteUpdatedSuccessfully', locale))
+}
+
+/**
+ * Copy an existing Quote.
+ */
+def copyQuote() {
+ if (!security.hasEntityPermission('ORDERMGR', '_CREATE', userLogin)) {
+ return error(UtilProperties.getMessage('OrderErrorUiLabels', 'OrderSecurityErrorToRunCopyQuote', locale))
+ }
+ GenericValue quote = from('Quote').where(parameters).queryOne()
+ if (!quote) {
+ return error(UtilProperties.getMessage('OrderErrorUiLabels', 'OrderQuoteDoesNotExists', locale))
+ }
+ Map serviceResult = run service: 'createQuote', with: [*:quote, statusId: null]
+ String quoteIdTo = serviceResult.quoteId
+
+ // Copy quoteItems.
+ if ('Y' == parameters.copyQuoteItems) {
+ List quoteItems = quote.getRelated('QuoteItem', null, null, false)
+ for (GenericValue quoteItem : quoteItems) {
+ Map serviceContext = dctx.makeValidContext('createQuoteItem', ModelService.IN_PARAM, [*: quoteItem, quoteId: quoteIdTo, userLogin: userLogin])
+ serviceResult = dispatcher.runSync('createQuoteItem', serviceContext)
+ if (ServiceUtil.isError(serviceResult)) {
+ return serviceResult
+ }
+ }
+ }
+
+ // Copy quoteAdjustments.
+ if ('Y' == parameters.copyQuoteAdjustments) {
+ List quoteAdjustments = quote.getRelated('QuoteAdjustment', null, null, false)
+ for (GenericValue quoteAdjustement : quoteAdjustments) {
+ if (!quoteAdjustment.quoteItemSeqId) {
+ Map serviceContext = dctx.makeValidContext('createQuoteAdjustment', ModelService.IN_PARAM, [*: quoteAdjustement, quoteId: quoteIdTo, userLogin: userLogin])
+ serviceResult = dispatcher.runSync('createQuoteAdjustment', serviceContext)
+ if (ServiceUtil.isError(serviceResult)) {
+ return serviceResult
+ }
+ }
+ }
+ }
+
+ // Copy quoteRoles.
+ if ('Y' == parameters.copyQuoteRoles) {
+ List quoteRoles = quote.getRelated('QuoteRole', null, null, false)
+ for (GenericValue quoteRole : quoteRoles) {
+ if (quoteRole.roleTypeId != 'REQ_TAKER') {
+ Map serviceContext = dctx.makeValidContext('createQuoteRole', ModelService.IN_PARAM, [*: quoteRole, quoteId: quoteIdTo, userLogin: userLogin])
+ serviceResult = dispatcher.runSync('createQuoteRole', serviceContext)
+ if (ServiceUtil.isError(serviceResult)) {
+ return serviceResult
+ }
+ }
+ }
+ }
+
+ // Copy quoteAttributes.
+ if ('Y' == parameters.copyQuoteAttributes) {
+ List quoteAttributes = quote.getRelated('QuoteAttribute', null, null, false)
+ for (GenericValue quoteAttribute : quoteAttributes) {
+ Map serviceContext = dctx.makeValidContext('createQuoteAttribute', ModelService.IN_PARAM, [*: quoteAttribute, quoteId: quoteIdTo, userLogin: userLogin])
+ serviceResult = dispatcher.runSync('createQuoteAttribute', serviceContext)
+ if (ServiceUtil.isError(serviceResult)) {
+ return serviceResult
+ }
+ }
+ }
+
+ // Copy quoteCoefficients.
+ if ('Y' == parameters.copyQuoteCoefficients) {
+ List quoteCoefficients = quote.getRelated('QuoteCoefficient', null, null, false)
+ for (GenericValue quoteCoefficient : quoteCoefficients) {
+ Map serviceContext = dctx.makeValidContext('createQuoteCoefficient', ModelService.IN_PARAM, [*: quoteCoefficient, quoteId: quoteIdTo, userLogin: userLogin])
+ serviceResult = dispatcher.runSync('createQuoteCoefficient', serviceContext)
+ if (ServiceUtil.isError(serviceResult)) {
+ return serviceResult
+ }
+ }
+ }
+
+ // Copy quoteTerms.
+ if ('Y' == parameters.copyQuoteTerms) {
+ List quoteTerms = quote.getRelated('QuoteTerm', null, null, false)
+ for (GenericValue quoteTerm : quoteTerms) {
+ Map serviceContext = dctx.makeValidContext('createQuoteTerm', ModelService.IN_PARAM, [*: quoteTerm, quoteId: quoteIdTo, userLogin: userLogin])
+ serviceResult = dispatcher.runSync('createQuoteTerm', serviceContext)
+ if (ServiceUtil.isError(serviceResult)) {
+ return serviceResult
+ }
+ }
+ }
+ def msg = UtilProperties.getMessage('OrderUiLabels', 'OrderOrderQuoteCreatedSuccessfully', locale);
+ return [successMessage: msg, quoteId: quoteIdTo]
+}
+
def ensureWorkEffortAndCreateQuoteWorkEffort() {
String workEffortId = parameters.workEffortId
if (!workEffortId) {
@@ -43,3 +316,402 @@ def ensureWorkEffortAndCreateQuoteWorkEf
serviceResult.workEffortId = workEffortId
return serviceResult
}
+/**
+ * Create a new QuoteItem, calculate the quoteUnitPrice from config or productPrice if not given.
+ */
+def createQuoteItem() {
+ GenericValue quote = from('Quote').where(parameters).queryOne()
+ if (!quote) {
+ return error(UtilProperties.getMessage('OrderErrorUiLabels', 'OrderQuoteDoesNotExists', locale))
+ }
+ if (!security.hasEntityPermission('ORDERMGR', '_CREATE', userLogin)) {
+ return error(UtilProperties.getMessage('OrderErrorUiLabels', 'OrderSecurityErrorToRunCreateQuoteItem', locale))
+ }
+ GenericValue quoteItem = delegator.makeValidValue('QuoteItem', parameters)
+ if (!quoteItem.quoteItemSeqId) {
+ delegator.setNextSubSeqId(quoteItem, 'quoteItemSeqId', 5, 1)
+ }
+
+ if (!parameters.quoteUnitPrice && parameters.productId) {
+ GenericValue product = from('Product').where(parameters).cache().queryOne()
+ if (product?.isVirtual == 'Y') {
+ return error(UtilProperties.getMessage('OrderErrorUiLabels', 'OrderCannotAddVirtualProductToQuote', locale))
+ }
+ if (product?.productTypeId?.startsWith('AGGREGATED')
+ && parameters.configId) {
+ ProductConfigWrapper configWrapper = ProductConfigWorker.loadProductConfigWrapper(delegator, dispatcher, parameters.configId, product.productId, null, null, null, null, locale, userLogin)
+ quoteItem.quoteUnitPrice = configWrapper.getTotalPrice()
+ } else {
+ Map serviceResult = run service: 'calculateProductPrice', with: [
+ product: product,
+ quantity: quoteItem.quantity,
+ amount: parameters.selectedAmount
+ ]
+ quoteItem.quoteUnitPrice = serviceResult.price
+ }
+ }
+ quoteItem.create()
+ return [successMessage: null, quoteId: quoteItem.quoteId, quoteItemSeqId: quoteItem.quoteItemSeqId]
+}
+
+/**
+ * Update an existing QuoteItem.
+ */
+def updateQuoteItem() {
+ if (!security.hasEntityPermission('ORDERMGR', '_UPDATE', userLogin)) {
+ return error(UtilProperties.getMessage('OrderErrorUiLabels', 'OrderSecurityErrorToRunUpdateQuoteItem', locale))
+ }
+
+ Map pksQuoteItem = [quoteId: parameters.quoteId, quoteItemSeqId: parameters.quoteItemSeqId]
+ GenericValue quoteItem = from('QuoteItem').where(pksQuoteItem).queryOne()
+ if (!quoteItem) {
+ return error(UtilProperties.getMessage('OrderErrorUiLabels', 'OrderQuoteItemDoesNotExists', locale))
+ }
+ quoteItem.setNonPKFields(parameters)
+ quoteItem.store()
+ return success()
+}
+
+/**
+ * Remove a QuoteItem.
+ */
+def removeQuoteItem() {
+ Map pksQuoteItem = [quoteId: parameters.quoteId, quoteItemSeqId: parameters.quoteItemSeqId]
+ GenericValue quoteItem = from('QuoteItem').where(pksQuoteItem).queryOne()
+ if (!quoteItem) {
+ return error(UtilProperties.getMessage('OrderErrorUiLabels', 'OrderQuoteItemDoesNotExists', locale))
+ }
+ delegator.removeByAnd('QuoteTerm', pksQuoteItem)
+ delegator.removeByAnd('QuoteAdjustment', pksQuoteItem)
+ quoteItem.remove()
+ return success()
+}
+
+/**
+ * Copy an existing QuoteItem.
+ */
+def copyQuoteItem() {
+ if (!security.hasEntityPermission('ORDERMGR', '_CREATE', userLogin)) {
+ return error(UtilProperties.getMessage('OrderErrorUiLabels', 'OrderSecurityErrorToRunCopyQuoteItem', locale))
+ }
+ GenericValue quoteItem = from('QuoteItem').where(parameters).queryOne()
+ if (!quoteItem) {
+ return error(UtilProperties.getMessage('OrderUiLabels', 'OrderQuoteItemDoesNotExists', locale))
+ }
+ Map input = [
+ userLogin: userLogin,
+ *: quoteItem,
+ quoteId: parameters.quoteIdTo,
+ quoteItemSeqId: parameters.quoteItemSeqIdTo
+ ]
+ if (!parameters.quoteIdTo && !parameters.quoteItemSeqIdTo) {
+ input.quoteItemSeqId = null
+ }
+ Map serviceResult = run service: 'createQuoteItem', with: input
+ if ('Y' == parameters.copyQuoteAdjustments) {
+ List quoteAdjustments = quoteItem.getRelated('QuoteAdjustment', null, null, false)
+ for (GenericValue quoteAdjustment : quoteAdjustments) {
+ Map serviceContext = dctx.makeValidContext('createQuoteAdjustment', ModelService.IN_PARAM, [*: quoteAdjustment, quoteId: parameters.quoteIdTo, quoteItemSeqId: parameters.quoteItemSeqIdTo, userLogin: userLogin])
+ serviceResult = dispatcher.runSync('createQuoteAdjustment', serviceContext)
+ if (ServiceUtil.isError(serviceResult)) {
+ return serviceResult
+ }
+ }
+ }
+
+ return success()
+}
+
+/**
+ * Create a new Quote and QuoteItem for a given CustRequest.
+ */
+def createQuoteAndQuoteItemForRequest() {
+ if (!security.hasEntityPermission('ORDERMGR', '_CREATE', userLogin)) {
+ return error(UtilProperties.getMessage('OrderErrorUiLabels', 'OrderSecurityErrorToRunCreateQuoteAndQuoteItemForRequest', locale))
+ }
+ GenericValue custRequest = from('CustRequest').where(parameters).queryOne()
+ GenericValue custRequestItem = from('CustRequestItem').where(parameters).queryOne()
+ if (!custRequest) {
+ return error(UtilProperties.getMessage('OrderErrorUiLabels', 'OrderErrorCustRequestWithIdDoesntExist', locale))
+ }
+
+ Map input = [
+ userLogin: userLogin,
+ *: parameters,
+ *: custRequest,
+ quoteTypeId: 'PROPOSAL',
+ partyId: custRequest.fromPartyId,
+ quoteName: custRequest.custRequestName,
+ currencyUomId: custRequest.maximumAmountUomId
+ ]
+ if (!input.statusId) {
+ input.statusId = 'QUO_CREATED'
+ }
+ Map serviceResult = run service: 'createQuote', with: input
+ String quoteId = serviceResult.quoteId
+
+ serviceResult = run service: 'createQuoteItem', with: [
+ *: custRequestItem,
+ comments: custRequestItem.story,
+ quoteId: quoteId
+ ]
+ String quoteItemSeqId = serviceResult.quoteItemSeqId
+
+ // copy the roles from the request to the quote
+ List custRequestParties = from('CustRequestParty').where(custRequestId: custRequest.custRequestId).queryList()
+ custRequestParties?.each { GenericValue custPartyRole ->
+ serviceResult = run service: 'createQuoteRole', with: [*: custPartyRole, quoteId: quoteId]
+ }
+
+ return [successMessage: null, quoteId: quoteId, quoteItemSeqId: quoteItemSeqId]
+}
+
+/**
+ * Create a Quote from a ShoppingCart.
+ */
+def createQuoteFromCart() {
+ ShoppingCart cart = (ShoppingCart) parameters.cart
+
+ Map createQuoteInMap = parameters
+ createQuoteInMap.partyId = cart.getPartyId()
+
+ if (createQuoteInMap.partyId
+ && createQuoteInMap.partyId != userLogin.partyId
+ && !security.hasEntityPermission('ORDERMGR', '_CREATE', userLogin)) {
+ return error(UtilProperties.getMessage('OrderErrorUiLabels', 'OrderSecurityErrorToRunCreateQuoteFromCart', locale))
+ }
+
+ createQuoteInMap.currencyUomId = cart.getCurrency()
+ createQuoteInMap.salesChannelEnumId = cart.getChannelType()
+
+ String orderType = cart.getOrderType()
+ if (orderType && orderType == 'SALES_ORDER') {
+ createQuoteInMap.productStoreId = cart.getProductStoreId()
+ createQuoteInMap.quoteTypeId = 'PRODUCT_QUOTE'
+ }
+ if (orderType && orderType == 'PURCHASE_ORDER') {
+ createQuoteInMap.quoteTypeId = 'PURCHASE_QUOTE'
+ }
+
+ createQuoteInMap.statusId = 'QUO_CREATED'
+
+ Map serviceResult = run service: 'createQuote', with: createQuoteInMap
+ GenericValue quote = from('Quote').where('quoteId', serviceResult.quoteId).queryOne()
+
+ cart.items()?.each { ShoppingCartItem item ->
+ Map createQuoteItemInMap = [userLogin: userLogin, locale: locale]
+ if (item.getIsPromo()) {
+ createQuoteItemInMap.isPromo = 'Y'
+ }
+ if (item.getConfigWrapper()) {
+ createQuoteItemInMap.configId = item.getConfigWrapper().getConfigId()
+ }
+
+ if (parameters.applyStorePromotions != 'N' || createQuoteItemInMap.isPromo != 'Y') {
+ createQuoteItemInMap.quoteId = quote.quoteId
+ createQuoteItemInMap.productId = item.getProductId()
+ createQuoteItemInMap.quantity = item.getQuantity()
+ createQuoteItemInMap.selectedAmount = item.getSelectedAmount()
+ createQuoteItemInMap.quoteUnitPrice = item.getBasePrice()
+ createQuoteItemInMap.comments = item.getItemComment()
+ createQuoteItemInMap.reservStart = item.getReservStart()
+ createQuoteItemInMap.reservLength = item.getReservLength()
+ createQuoteItemInMap.reservPersons = item.getReservPersons()
+
+ Map serviceQuoteItemResult = run service: 'createQuoteItem', with: createQuoteItemInMap
+ //and the quoteItemSeqId is assigned to the shopping cart item (as orderItemSeqId)
+ item.setOrderItemSeqId(serviceQuoteItemResult.quoteItemSeqId)
+ }
+ if (parameters.applyStorePromotions != 'N') {
+ cart.makeAllQuoteAdjustments()?.each { GenericValue adjustment ->
+ adjustment.quoteId = quote.quoteId
+ adjustment.quoteAdjustmentId = delegator.getNextSeqId('QuoteAdjustment')
+ adjustment.create()
+ }
+ }
+ }
+ return [successMessage: null, quoteId: quote.quoteId]
+}
+
+/**
+ * Create a Quote from a Shopping List.
+ */
+def createQuoteFromShoppingList() {
+ Map serviceResult = run service: 'loadCartFromShoppingList', with: parameters
+ serviceResult = run service: 'createQuoteFromCart', with: [
+ cart: serviceResult.shoppingCart,
+ applyStorePromotions: parameters.applyStorePromotions
+ ]
+ return [successMessage: null, quoteId: serviceResult.quoteId]
+}
+
+/**
+ * Auto update a QuoteItem price.
+ */
+def autoUpdateQuotePrice() {
+ if (!security.hasEntityPermission('ORDERMGR', '_UPDATE', userLogin)) {
+ return error(UtilProperties.getMessage('OrderErrorUiLabels', 'OrderSecurityErrorToRunAutoUpdateQuotePrice', locale))
+ }
+ GenericValue quoteItem = from('QuoteItem').where(parameters).queryOne()
+ if (!quoteItem) {
+ return error(UtilProperties.getMessage('OrderUiLabels', 'OrderQuoteItemDoesNotExists', locale))
+ }
+ if (parameters.manualQuoteUnitPrice) {
+ quoteItem.quoteUnitPrice = parameters.manualQuoteUnitPrice
+ } else if (parameters.defaultQuoteUnitPrice) {
+ quoteItem.quoteUnitPrice = parameters.defaultQuoteUnitPrice
+ }
+ quoteItem.store()
+ return success()
+}
+
+/**
+ * Create a Quote from a CustRequest.
+ */
+def createQuoteFromCustRequest() {
+ if (!security.hasEntityPermission('ORDERMGR', '_CREATE', userLogin)) {
+ return error(UtilProperties.getMessage('OrderErrorUiLabels', 'OrderSecurityErrorToRunCreateQuoteFromCustRequest', locale))
+ }
+
+ GenericValue custRequest = from('CustRequest').where('custRequestId', parameters.custRequestId).queryOne()
+
+ // Error if request type not equals to RF_QUOTE or RF_PUR_QUOTE
+ if (custRequest.custRequestTypeId != 'RF_QUOTE' && custRequest.custRequestTypeId != 'RF_PUR_QUOTE') {
+ return error(UtilProperties.getMessage('OrderErrorUiLabels', 'OrderQuoteNotARequest', locale))
+ }
+
+ Map createQuoteInMap = [
+ partyId: custRequest.fromPartyId,
+ productStoreId: custRequest.productStoreId,
+ salesChannelEnumId: custRequest.salesChannelEnumId,
+ quoteName: custRequest.custRequestName,
+ description: custRequest.description,
+ currencyUomId: custRequest.maximumAmountUomId,
+ statusId: 'QUO_CREATED'
+ ]
+
+ // Set the quoteType (product or purchase)
+ if (parameters.quoteTypeId) {
+ createQuoteInMap.quoteTypeId = parameters.quoteTypeId
+ } else if (custRequest.custRequestTypeId == 'RF_QUOTE') {
+ createQuoteInMap.quoteTypeId = 'PRODUCT_QUOTE'
+ } else {
+ createQuoteInMap.quoteTypeId = 'PURCHASE_QUOTE'
+ }
+
+ Map serviceResult = run service: 'createQuote', with: createQuoteInMap
+ String quoteId = serviceResult.quoteId
+
+ exprdCond = [
+ EntityCondition.makeCondition('custRequestId', custRequest.custRequestId),
+ EntityCondition.makeCondition('statusId', EntityOperator.NOT_EQUAL, 'CRQ_CANCELLED'),
+ EntityCondition.makeCondition('statusId', EntityOperator.NOT_EQUAL, 'CRQ_REJECTED')
+ ]
+ List custRequestItems = from('CustRequestItem').where(exprdCond).queryList()
+
+ custRequestItems.each { GenericValue custRequestItem ->
+ Map serviceCQIResult = run service: 'createQuoteItem', with: [*:custRequestItem, quoteId: quoteId]
+ }
+
+ // Roles
+ custRequest.getRelated('CustRequestParty', null, null, false)?.each { GenericValue custRequestParty ->
+ run service: 'createQuoteRole', with: [
+ quoteId: quoteId,
+ partyId: custRequestParty.partyId,
+ roleTypeId: custRequestParty.roleTypeId
+ ]
+ }
+
+ return [successMessage: null, quoteId: quoteId]
+}
+
+/**
+ * Auto create QuoteAdjustments.
+ */
+def autoCreateQuoteAdjustments() {
+ if (!security.hasEntityPermission('ORDERMGR', '_CREATE', userLogin)) {
+ return error(UtilProperties.getMessage('OrderErrorUiLabels', 'OrderSecurityErrorToRunAutoCreateQuoteAdjustments', locale))
+ }
+ String quoteId = parameters.quoteId
+ GenericValue quote = from('Quote').where('quoteId', quoteId).queryOne()
+ if (!quote) {
+ return error(UtilProperties.getMessage('OrderErrorUiLabels', 'OrderQuoteDoesNotExists', locale))
+ }
+
+ // All existing promo quote items are removed.
+ quote.getRelated('QuoteItem', [isPromo: 'Y'], null, false)?.each { GenericValue quoteItem ->
+ run service: 'removeQuoteItem', with: [*: quoteItem]
+ }
+
+ // All existing auto quote adjustments are removed.
+ quote.getRelated('QuoteAdjustment', null, null, false)?.each { GenericValue quoteAdjustment ->
+ // Make sure this is not a manual adjustments
+ if (quoteAdjustment.productPromoId) {
+ run service: 'removeQuoteAdjustment', with: [*: quoteAdjustment]
+ }
+ }
+
+ Map serviceResult = run service: 'loadCartFromQuote', with: [*: parameters, applyQuoteAdjustments: false]
+ ShoppingCart shoppingCart = (ShoppingCart) serviceResult.shoppingCart
+
+ shoppingCart.items()?.each { ShoppingCartItem item ->
+ String orderItemSeqId = item.getOrderItemSeqId()
+ if (!orderItemSeqId) {
+ // This is a new (promo) item, a new quote item is created
+ serviceResult = run service: 'createQuoteItem', with: [
+ quoteId: quoteId,
+ quantity: item.getQuantity(),
+ productId: item.getProductId(),
+ isPromo: 'Y'
+ ]
+ // and the quoteItemSeqId is assigned to the shopping cart item (as orderItemSeqId).
+ item.setOrderItemSeqId(serviceResult.quoteItemSeqId)
+ }
+ }
+
+ // Set the quoteUnitPrice from the item basePrice.
+ quote.getRelated('QuoteItem', null, null, false)?.each { GenericValue quoteItem ->
+ if (!quoteItem.quoteUnitPrice || quoteItem.quoteUnitPrice == 0) {
+ ShoppingCartItem item = shoppingCart.findCartItem(quoteItem.quoteItemSeqId)
+ if (item) {
+ quoteItem.quoteUnitPrice = item.getBasePrice()
+ run service: 'updateQuoteItem', with: [*: quoteItem]
+ }
+ }
+ }
+ shoppingCart.makeAllQuoteAdjustments()?.each { GenericValue adjustment ->
+ adjustment.quoteId = quoteId
+ run service: 'createQuoteAdjustment', with: [*: adjustment]
+ }
+ return success()
+}
+
+/**
+ * Create a new Note associated with a Quote
+ */
+def createQuoteNote() {
+ // Passed in field will be noteInfo, which matches entity, but service expects field called note.
+ Map serviceContext = dctx.makeValidContext('createNote', ModelService.IN_PARAM, [*: parameters, note: parameters.noteInfo])
+ Map serviceResult = dispatcher.runSync('createNote', serviceContext)
+ if (ServiceUtil.isError(serviceResult)) {
+ return error(UtilProperties.getMessage('OrderErrorUiLabels', 'OrderProblemCreatingTheNoteNoNoteIdReturned', locale))
+ }
+ GenericValue quoteNote = makeValue('QuoteNote')
+ quoteNote.quoteId = parameters.quoteId
+ quoteNote.noteId = serviceResult.noteId
+ quoteNote.create()
+ return success()
+}
+
+/**
+ * Create a Quote adjustment
+ */
+def createQuoteAdjustment() {
+ GenericValue quoteAdjustment = makeValue('QuoteAdjustment', parameters)
+ quoteAdjustment.quoteAdjustmentId = delegator.getNextSeqId("QuoteAdjustment")
+ quoteAdjustment.createdByUserLogin = userLogin.userLoginId
+ quoteAdjustment.createdDate = UtilDateTime.nowTimestamp()
+ quoteAdjustment.create()
+ return [successMessage: null, quoteAdjustmentId: quoteAdjustment.quoteAdjustmentId]
+}
+
Added: ofbiz/ofbiz-framework/trunk/applications/order/groovyScripts/test/QuoteTests.groovy
URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/order/groovyScripts/test/QuoteTests.groovy?rev=1849800&view=auto
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/order/groovyScripts/test/QuoteTests.groovy (added)
+++ ofbiz/ofbiz-framework/trunk/applications/order/groovyScripts/test/QuoteTests.groovy Thu Dec 27 14:40:03 2018
@@ -0,0 +1,515 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.ofbiz.testtools.GroovyScriptTestCase
+import org.apache.ofbiz.order.shoppingcart.ShoppingCart
+import org.apache.ofbiz.entity.util.EntityQuery
+import org.apache.ofbiz.entity.GenericValue
+import org.apache.ofbiz.service.ServiceUtil
+import org.apache.ofbiz.base.util.Debug
+
+import java.sql.Timestamp
+
+import static org.apache.ofbiz.base.util.UtilDateTime.nowTimestamp
+import static org.apache.ofbiz.entity.condition.EntityCondition.makeCondition
+import static org.apache.ofbiz.entity.condition.EntityComparisonOperator.GREATER_THAN_EQUAL_TO
+
+class QuoteTests extends GroovyScriptTestCase {
+
+ // Retrieves a particular login record.
+ private GenericValue getUserLogin(String userLoginId) {
+ GenericValue userLogin = EntityQuery.use(delegator)
+ .from('UserLogin').where(userLoginId: userLoginId).queryOne()
+ assert userLogin
+ return userLogin
+ }
+
+ // Test case for successfully creating a QuoteWorkEffort record.
+ void testCreateQuoteWorkEffort() {
+ GenericValue userLogin = getUserLogin('DemoRepStore')
+
+ def quoteId = '9001'
+ def workEffortId = '9007'
+
+ def input = [userLogin: userLogin, quoteId: quoteId, workEffortId: workEffortId]
+ Map serviceResult = dispatcher.runSync('ensureWorkEffortAndCreateQuoteWorkEffort', input)
+
+ // Confirm the service output parameters.
+ assert ServiceUtil.isSuccess(serviceResult)
+ assert serviceResult.workEffortId == input.workEffortId
+
+ // Confirm the database changes.
+ GenericValue quoteWorkEffort = EntityQuery.use(delegator)
+ .from('QuoteWorkEffort').where(quoteId: quoteId, workEffortId: workEffortId).queryOne()
+ assert quoteWorkEffort
+ }
+
+ // Test case for unsuccessfully creating a QuoteWorkEffort record by attempting
+ // to use a quoteId and workEffortId that has already been used in an existing
+ // QuoteWorkEffortRecord.
+ void testCreateQuoteWorkEffortFail() {
+ // Use to confirm nothing has changed at the end of the test
+ Timestamp startTime = nowTimestamp()
+ GenericValue userLogin = getUserLogin('DemoRepStore')
+
+ def quoteId = '9001'
+ def workEffortId = '9007'
+
+ // Execute the service, note break-on-error is false so that the test
+ // itself doesn't fail and we also need a separate transaction so our
+ // lookup below doesn't fail due to the rollback
+ def input = [userLogin: userLogin, quoteId: quoteId, workEffortId: workEffortId]
+ Map serviceResult
+ try {
+ serviceResult = dispatcher.runSync('ensureWorkEffortAndCreateQuoteWorkEffort', input)
+ } catch (Exception e) {
+ serviceResult = ServiceUtil.returnError(e.toString())
+ }
+ assert ServiceUtil.isError(serviceResult)
+
+ // Confirm the database changes, in this case nothing should have changed
+ GenericValue quoteWorkEffort = EntityQuery.use(delegator)
+ .from('QuoteWorkEffort').where(
+ makeCondition(quoteId: quoteId, workEffortId: workEffortId),
+ makeCondition('lastUpdatedStamp', GREATER_THAN_EQUAL_TO, startTime)
+ ).queryOne()
+
+ assert !quoteWorkEffort
+ }
+
+ // Test case for CheckUpdateQuotestatus
+ void testCheckUpdateQuotestatus() {
+ GenericValue userLogin = getUserLogin('system')
+ def input = [
+ userLogin: userLogin,
+ quoteId: '9001',
+ ]
+
+ Map serviceResult = dispatcher.runSync('checkUpdateQuoteStatus', input)
+ assert ServiceUtil.isSuccess(serviceResult)
+ GenericValue quote = EntityQuery.use(delegator).from('Quote').where(quoteId: '9001').queryOne()
+ assert quote.statusId == 'QUO_ORDERED'
+ }
+
+ // Test case for calling createQuoteWorkEffort without a workEffortId which
+ // triggers an ECA to create the WorkEffort first.
+ void testCreateWorkEffortAndQuoteWorkEffort() {
+ GenericValue userLogin = getUserLogin('flexadmin')
+
+ // Use the bare minimum inputs necessary to create the work effort as we
+ // aren't testing that service, only that it plays well as an ECA.
+ def input = [
+ currentStatusId: 'ROU_ACTIVE',
+ workEffortName: 'Test WorkEffort',
+ workEffortTypeId: 'ROUTING',
+ quoteId: '9000',
+ userLogin: userLogin
+ ]
+ Map serviceResult = dispatcher.runSync('ensureWorkEffortAndCreateQuoteWorkEffort', input)
+ assert ServiceUtil.isSuccess(serviceResult)
+ assert serviceResult.workEffortId
+
+ // Confirm that a matching WorkEffort was created.
+ GenericValue workEfforts = EntityQuery.use(delegator)
+ .from('WorkEffort').where(
+ workEffortId: serviceResult.workEffortId,
+ currentStatusId: input.currentStatusId,
+ workEffortName: input.workEffortName,
+ workEffortTypeId: input.workEffortTypeId
+ ).queryOne()
+ assert workEfforts
+
+ GenericValue quoteWorkEffort = EntityQuery.use(delegator)
+ .from('WorkEffort').where(
+ quoteId: input.quoteId,
+ workEffortId: serviceResult.workEffortId
+ ).queryOne()
+ assert quoteWorkEffort
+ }
+
+ // Test createQuote service
+ void testCreateQuote () {
+ GenericValue userLogin = getUserLogin('system')
+ Map input = [
+ userLogin: userLogin,
+ partyId: 'Company'
+ ]
+ Map serviceResult = dispatcher.runSync('createQuote', input)
+ assert ServiceUtil.isSuccess(serviceResult)
+ assert serviceResult.quoteId
+ GenericValue quote = EntityQuery.use(delegator).from('Quote').where(quoteId: serviceResult.quoteId).queryOne()
+ assert quote
+ }
+
+ // Test updateQuote service
+ void testUpdateQuote() {
+ GenericValue userLogin = getUserLogin('system')
+ Map input = [
+ userLogin: userLogin,
+ quoteId: '9000',
+ statusId: 'QUO_APPROVED'
+ ]
+ Map serviceResult = dispatcher.runSync('updateQuote', input)
+ assert ServiceUtil.isSuccess(serviceResult)
+ GenericValue quote = EntityQuery.use(delegator).from('Quote').where(quoteId: '9000').queryOne()
+ assert quote.statusId == 'QUO_APPROVED'
+
+ input.statusId = 'QUO_CREATED'
+ serviceResult = dispatcher.runSync('updateQuote', input)
+ assert ServiceUtil.isError(serviceResult)
+ }
+
+ // Test copyQuote service
+ void testCopyQuote() {
+ GenericValue userLogin = getUserLogin('system')
+ Map input = [
+ userLogin: userLogin,
+ quoteId: '9000'
+ ]
+ Map serviceResult = dispatcher.runSync('copyQuote', input)
+ assert ServiceUtil.isSuccess(serviceResult)
+ assert serviceResult.quoteId
+ }
+
+ // Test createQuoteItem service
+ void testCreateQuoteItem() {
+ GenericValue userLogin = getUserLogin('system')
+ Map input = [
+ userLogin: userLogin,
+ quoteId: '9000',
+ quoteItemSeqId: '00004',
+ productId: 'GZ-1001'
+ ]
+ Map serviceResult = dispatcher.runSync('createQuoteItem', input)
+ assert ServiceUtil.isSuccess(serviceResult)
+ GenericValue quoteItem = EntityQuery.use(delegator).from('QuoteItem').where(quoteId: '9000', quoteItemSeqId: '00004').queryOne()
+ assert quoteItem.quoteUnitPrice
+ }
+
+ // Test updateQuoteItem service
+ void testUpdateQuoteItem() {
+ GenericValue userLogin = getUserLogin('system')
+
+ Map input = [
+ userLogin: userLogin,
+ quoteId: '9000',
+ quoteItemSeqId: '00002',
+ productId: 'GZ-1001'
+ ]
+ Map serviceResult = dispatcher.runSync('updateQuoteItem', input)
+ assert ServiceUtil.isSuccess(serviceResult)
+ GenericValue quoteItem = EntityQuery.use(delegator).from('QuoteItem').where(quoteId: '9000', quoteItemSeqId: '00002').queryOne()
+ assert quoteItem.productId == 'GZ-1001'
+ }
+
+ // Test removeQuoteItem service
+ void testRemoveQuoteItem() {
+ GenericValue userLogin = getUserLogin('system')
+
+ Map input = [
+ userLogin: userLogin,
+ quoteId: '9000',
+ quoteItemSeqId: '00002'
+ ]
+ Map serviceResult = dispatcher.runSync('removeQuoteItem', input)
+ assert ServiceUtil.isSuccess(serviceResult)
+ GenericValue quoteItem = EntityQuery.use(delegator).from('QuoteItem').where(quoteId: '9000', quoteItemSeqId: '00002').queryOne()
+ assert !quoteItem
+ GenericValue quoteTerm = EntityQuery.use(delegator).from('QuoteTerm').where(quoteId: '9000', quoteItemSeqId: '00002', termTypeId: 'FIN_PAYMENT_DISC').queryOne()
+ assert !quoteTerm
+ }
+
+ // test create a Term
+ void testCreateQuoteTerm () {
+ GenericValue userLogin = getUserLogin('system')
+ def input = [
+ userLogin: userLogin,
+ termTypeId: 'FIN_PAYMENT_DISC',
+ quoteId: '9000',
+ quoteItemSeqId: '00001',
+ termValue: 40L,
+ termDays: 4L,
+ uomId: 'CNY',
+ description: 'create quoteTerm'
+ ]
+
+ Map serviceResult = dispatcher.runSync('createQuoteTerm', input)
+ List<GenericValue> terms = EntityQuery.use(delegator).from('QuoteTerm')
+ .where(termTypeId: 'FIN_PAYMENT_DISC', quoteId: '9000', quoteItemSeqId: '00001').queryList()
+
+ assert ServiceUtil.isSuccess(serviceResult)
+ assert terms
+ GenericValue term = terms[0]
+ assert input.termTypeId == term.termTypeId
+ assert input.termValue == term.termValue
+ assert input.termDays == term.termDays
+ assert input.uomId == term.uomId
+ assert input.description == term.description
+ }
+
+ // Update a term.
+ void testUpdateQuoteTerm() {
+ GenericValue userLogin = getUserLogin('system')
+ def input = [
+ termTypeId: 'FIN_PAYMENT_DISC',
+ quoteId: '9000',
+ quoteItemSeqId: '00002',
+ termValue: 30L,
+ termDays: 3L,
+ uomId: 'CNY',
+ description: 'update quoteterm',
+ userLogin: userLogin
+ ]
+ Map serviceResult = dispatcher.runSync('updateQuoteTerm', input)
+ assert ServiceUtil.isSuccess(serviceResult)
+
+ // Confirm that a matching Quoteterm was updated
+ GenericValue quoteTerm = EntityQuery.use(delegator)
+ .from('QuoteTerm').where(
+ termTypeId: input.termTypeId,
+ quoteId: input.quoteId,
+ quoteItemSeqId: input.quoteItemSeqId
+ ).queryOne()
+ assert quoteTerm
+ assert quoteTerm.termTypeId == input.termTypeId
+ assert quoteTerm.quoteId == input.quoteId
+ assert quoteTerm.quoteItemSeqId == input.quoteItemSeqId
+ assert quoteTerm.termValue == input.termValue
+ assert quoteTerm.termDays == input.termDays
+ assert quoteTerm.uomId == input.uomId
+ assert quoteTerm.description == input.description
+ }
+
+ // delete a term
+ void testDeleteQuoteTerm () {
+ GenericValue userLogin = getUserLogin('system')
+ def input = [
+ userLogin: userLogin,
+ termTypeId: 'FIN_PAYMENT_DISC',
+ quoteId: '9000',
+ quoteItemSeqId: '00003'
+ ]
+
+ Map serviceResult = dispatcher.runSync('deleteQuoteTerm', input)
+ assert ServiceUtil.isSuccess(serviceResult)
+ GenericValue quoteTerm = EntityQuery.use(delegator).from('QuoteTerm').where(termTypeId: serviceResult.termTypeId, quoteId: serviceResult.quoteId, quoteItemSeqId: serviceResult.quoteItemSeqId).queryOne()
+ assert !quoteTerm
+ }
+
+ // Create Quote Attribute
+ void testCreateQuoteAttribute () {
+ GenericValue userLogin = getUserLogin('system')
+ def input = [
+ userLogin: userLogin,
+ quoteId: '9001',
+ attrName: 'Test'
+ ]
+
+ Map serviceResult = dispatcher.runSync('createQuoteAttribute', input)
+ assert ServiceUtil.isSuccess(serviceResult)
+ }
+
+ // Create Quote Coefficient
+ void testCreateQuoteCoefficient () {
+ GenericValue userLogin = getUserLogin('system')
+ def input = [
+ userLogin: userLogin,
+ quoteId: '9001',
+ coeffName: 'Test'
+ ]
+
+ Map serviceResult = dispatcher.runSync('createQuoteCoefficient', input)
+ assert ServiceUtil.isSuccess(serviceResult)
+ }
+
+ // Get Next Quote Id
+ void testGetNextQuoteId () {
+ GenericValue userLogin = getUserLogin('system')
+ def input = [
+ userLogin: userLogin,
+ partyId: 'DemoCustomer-1'
+ ]
+
+ Map serviceResult = dispatcher.runSync('getNextQuoteId', input)
+ assert ServiceUtil.isSuccess(serviceResult)
+ assert serviceResult.quoteId
+ }
+
+ // Test Quote Sequence Enforced
+ void testQuoteSequenceEnforced() {
+ GenericValue userLogin = getUserLogin('system')
+ GenericValue partyAcctgPreference = EntityQuery.use(delegator)
+ .from('PartyAcctgPreference').where('partyId', 'DemoCustomer').queryOne()
+ Long lastQuoteNumber = partyAcctgPreference.lastQuoteNumber
+ if (!lastQuoteNumber) {
+ lastQuoteNumber = 0
+ }
+
+ def input = [
+ userLogin: userLogin,
+ partyId: 'DemoCustomer',
+ partyAcctgPreference: partyAcctgPreference
+ ]
+
+ Map serviceResult = dispatcher.runSync('quoteSequenceEnforced', input)
+ assert ServiceUtil.isSuccess(serviceResult)
+ assert serviceResult.quoteId == lastQuoteNumber +1L
+ }
+
+ // Copy Quote Item
+ void testCopyQuoteItem () {
+ GenericValue userLogin = getUserLogin('system')
+ def input = [
+ userLogin: userLogin,
+ quoteId: '9001',
+ quoteItemSeqId: '00001',
+ quoteIdTo: '9001',
+ quoteItemSeqIdTo: '00002',
+ copyQuoteAdjustments: 'Y'
+ ]
+
+ Map serviceResult = dispatcher.runSync('copyQuoteItem', input)
+ assert ServiceUtil.isSuccess(serviceResult)
+ GenericValue quoteAdjustment = EntityQuery.use(delegator).from('QuoteAdjustment').where('quoteId', '9001', 'quoteItemSeqId', '00002', 'quoteAdjustmentTypeId', 'SALES_TAX').queryFirst()
+ assert quoteAdjustment
+ }
+
+ // Test createQuoteAndQuoteItemForRequest
+ void testCreateQuoteAndQuoteItemForRequest () {
+ GenericValue userLogin = getUserLogin('system')
+ def input = [
+ userLogin: userLogin,
+ custRequestId: '9000',
+ custRequestItemSeqId: '00001'
+ ]
+ Map serviceResult = dispatcher.runSync('createQuoteAndQuoteItemForRequest', input)
+ assert ServiceUtil.isSuccess(serviceResult)
+ GenericValue quoteItem = EntityQuery.use(delegator).from('QuoteItem').where('quoteId', serviceResult.quoteId, 'custRequestItemSeqId', '00001').queryFirst()
+ assert quoteItem
+ }
+
+ // Test createQuoteFromCart
+ void testCreateQuoteFromCart() {
+ GenericValue userLogin = getUserLogin('system')
+ String productId = 'SV-1001'
+ String partyId = 'DemoCustomer'
+
+ ShoppingCart cart = new ShoppingCart(delegator, '9000', Locale.getDefault(), 'USD')
+ cart.setOrderType('SALES_ORDER')
+ cart.setChannelType('WEB_SALES_CHANNEL')
+ cart.setBillToCustomerPartyId(partyId)
+ cart.setPlacingCustomerPartyId(partyId)
+ cart.setShipToCustomerPartyId(partyId)
+ cart.setEndUserCustomerPartyId(partyId)
+ cart.setUserLogin(userLogin, dispatcher)
+ cart.addOrIncreaseItem(productId, null, BigDecimal.ONE, null, null, null,
+ null, null, null, null, 'DemoCatalog', null, null,
+ null, null, dispatcher)
+ cart.setDefaultCheckoutOptions(dispatcher)
+
+ def input = [
+ userLogin: userLogin,
+ cart: cart,
+ applyStorePromotions: 'Y'
+ ]
+ Map serviceResult = dispatcher.runSync('createQuoteFromCart', input)
+ assert ServiceUtil.isSuccess(serviceResult)
+ GenericValue quoteItem = EntityQuery.use(delegator).from('QuoteItem').where('quoteId', serviceResult.quoteId, 'productId', productId).queryFirst()
+ assert quoteItem
+ GenericValue quoteAdjustment = EntityQuery.use(delegator).from('QuoteAdjustment').where('quoteId', serviceResult.quoteId).queryFirst()
+ assert quoteAdjustment
+ }
+
+ // Test createQuoteFromShoppingList
+ void testCreateQuoteFromShoppingList() {
+ GenericValue userLogin = getUserLogin('system')
+ def input = [
+ userLogin: userLogin,
+ shoppingListId: '9000',
+ applyStorePromotions: 'Y'
+ ]
+ Map serviceResult = dispatcher.runSync('createQuoteFromShoppingList', input)
+ assert ServiceUtil.isSuccess(serviceResult)
+ GenericValue quoteItem = EntityQuery.use(delegator).from('QuoteItem').where('quoteId', serviceResult.quoteId, 'productId', 'SV-1001').queryFirst()
+ assert quoteItem
+ GenericValue quoteAdjustment = EntityQuery.use(delegator).from('QuoteAdjustment').where('quoteId', serviceResult.quoteId).queryFirst()
+ assert quoteAdjustment
+ }
+
+ // Test autoUpdateQuotePrice
+ void testAutoUpdateQuotePrice() {
+ GenericValue userLogin = getUserLogin('system')
+ def input = [
+ userLogin: userLogin,
+ quoteId: '9000',
+ quoteItemSeqId: '00001',
+ defaultQuoteUnitPrice: BigDecimal.valueOf(12)
+ ]
+ Map serviceResult = dispatcher.runSync('autoUpdateQuotePrice', input)
+ assert ServiceUtil.isSuccess(serviceResult)
+ GenericValue quoteItem = EntityQuery.use(delegator).from('QuoteItem').where('quoteId', '9000', 'quoteItemSeqId', '00001').queryOne()
+ assert quoteItem.quoteUnitPrice == 12
+ }
+
+ // Test createQuoteFromCustRequest
+ void testCreateQuoteFromCustRequest () {
+ GenericValue userLogin = getUserLogin('system')
+ def input = [
+ userLogin: userLogin,
+ custRequestId: '9000'
+ ]
+ Map serviceResult = dispatcher.runSync('createQuoteFromCustRequest', input)
+ assert ServiceUtil.isSuccess(serviceResult)
+ GenericValue quoteItem = EntityQuery.use(delegator).from('QuoteItem').where('quoteId', serviceResult.quoteId, 'custRequestId', '9000').queryFirst()
+ assert quoteItem
+ }
+
+ // Test autoCreateQuoteAdjustments
+ void testAutoCreateQuoteAdjustments () {
+ GenericValue userLogin = EntityQuery.use(delegator)
+ .from('UserLogin').where(userLoginId: 'system').queryOne()
+ assert userLogin
+ GenericValue quote = EntityQuery.use(delegator)
+ .from('Quote').where(quoteId: '9001').queryOne()
+
+ def input = [
+ userLogin: userLogin,
+ quoteId: '9001'
+ ]
+ Map serviceResult = dispatcher.runSync('autoCreateQuoteAdjustments', input)
+ assert ServiceUtil.isSuccess(serviceResult)
+ GenericValue promoQuoteAdjustment = EntityQuery.use(delegator).from('QuoteAdjustment').where('quoteId', '9001', 'quoteAdjustmentTypeId', 'PROMOTION_ADJUSTMENT').queryFirst()
+ assert promoQuoteAdjustment
+ }
+
+ // Create Quote Note
+ void testCreateQuoteNote () {
+ GenericValue userLogin = getUserLogin('system')
+ def input = [
+ userLogin: userLogin,
+ quoteId: '9001',
+ noteName: 'Test Note',
+ noteInfo: 'This is a test'
+ ]
+
+ Map serviceResult = dispatcher.runSync('createQuoteNote', input)
+ assert ServiceUtil.isSuccess(serviceResult)
+ }
+
+}
Propchange: ofbiz/ofbiz-framework/trunk/applications/order/groovyScripts/test/QuoteTests.groovy
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: ofbiz/ofbiz-framework/trunk/applications/order/groovyScripts/test/QuoteTests.groovy
------------------------------------------------------------------------------
svn:keywords = Date Rev Author URL Id
Propchange: ofbiz/ofbiz-framework/trunk/applications/order/groovyScripts/test/QuoteTests.groovy
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: ofbiz/ofbiz-framework/trunk/applications/order/ofbiz-component.xml
URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/order/ofbiz-component.xml?rev=1849800&r1=1849799&r2=1849800&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/order/ofbiz-component.xml (original)
+++ ofbiz/ofbiz-framework/trunk/applications/order/ofbiz-component.xml Thu Dec 27 14:40:03 2018
@@ -51,7 +51,7 @@ under the License.
<test-suite loader="main" location="testdef/FinAccountTests.xml"/>
<test-suite loader="main" location="testdef/OrderTest.xml"/>
<test-suite loader="main" location="testdef/CustRequestTests.xml"/>
- <test-suite loader="main" location="testdef/quotetests.xml"/>
+ <test-suite loader="main" location="testdef/QuoteTests.xml"/>
<test-suite loader="main" location="testdef/ShoppingListTests.xml"/>
<test-suite loader="main" location="testdef/ShoppingCartTests.xml"/>
Modified: ofbiz/ofbiz-framework/trunk/applications/order/servicedef/services_quote.xml
URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/order/servicedef/services_quote.xml?rev=1849800&r1=1849799&r2=1849800&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/order/servicedef/services_quote.xml (original)
+++ ofbiz/ofbiz-framework/trunk/applications/order/servicedef/services_quote.xml Thu Dec 27 14:40:03 2018
@@ -25,35 +25,35 @@ under the License.
<version>1.0</version>
<!-- Quote -->
- <service name="getNextQuoteId" engine="simple"
- location="component://order/minilang/quote/QuoteServices.xml" invoke="getNextQuoteId">
+ <service name="getNextQuoteId" engine="groovy"
+ location="component://order/groovyScripts/quote/QuoteServices.groovy" invoke="getNextQuoteId">
<description>Get the Next Quote ID According to Settings on the PartyAcctgPreference Entity for the given Party</description>
<implements service="createQuote"/>
- <attribute name="partyId" type="String" mode="IN" optional="false"/>
- <attribute name="quoteId" type="String" mode="OUT" optional="false"/>
+ <attribute name="partyId" type="String" mode="IN"/>
+ <attribute name="quoteId" type="String" mode="OUT"/>
</service>
- <service name="quoteSequenceEnforced" engine="simple"
- location="component://order/minilang/quote/QuoteServices.xml" invoke="quoteSequenceEnforced">
+ <service name="quoteSequenceEnforced" engine="groovy"
+ location="component://order/groovyScripts/quote/QuoteServices.groovy" invoke="quoteSequenceEnforced">
<implements service="getNextQuoteId" optional="true"/>
<attribute name="partyAcctgPreference" type="org.apache.ofbiz.entity.GenericValue" mode="IN"/>
<override name="quoteId" type="Long" mode="OUT"/>
</service>
- <service name="createQuote" default-entity-name="Quote" engine="simple"
- location="component://order/minilang/quote/QuoteServices.xml" invoke="createQuote" auth="true">
+ <service name="createQuote" default-entity-name="Quote" engine="groovy"
+ location="component://order/groovyScripts/quote/QuoteServices.groovy" invoke="createQuote" auth="true">
<description>Create an Quote</description>
<auto-attributes include="nonpk" mode="IN" optional="true"/>
<auto-attributes include="pk" mode="OUT" optional="true"/>
</service>
- <service name="updateQuote" default-entity-name="Quote" engine="simple"
- location="component://order/minilang/quote/QuoteServices.xml" invoke="updateQuote" auth="true">
+ <service name="updateQuote" default-entity-name="Quote" engine="groovy"
+ location="component://order/groovyScripts/quote/QuoteServices.groovy" invoke="updateQuote" auth="true">
<description>Update a Quote</description>
<auto-attributes include="pk" mode="IN" optional="false"/>
<auto-attributes include="nonpk" mode="IN" optional="true"/>
</service>
- <service name="copyQuote" default-entity-name="Quote" engine="simple"
- location="component://order/minilang/quote/QuoteServices.xml" invoke="copyQuote" auth="true">
+ <service name="copyQuote" default-entity-name="Quote" engine="groovy"
+ location="component://order/groovyScripts/quote/QuoteServices.groovy" invoke="copyQuote" auth="true">
<description>Copy a Quote</description>
<auto-attributes include="pk" mode="INOUT" optional="false"/>
<attribute name="copyQuoteRoles" type="String" mode="IN" optional="true"/>
@@ -63,11 +63,12 @@ under the License.
<attribute name="copyQuoteAdjustments" type="String" mode="IN" optional="true"/>
<attribute name="copyQuoteTerms" type="String" mode="IN" optional="true"/>
</service>
- <service name="checkUpdateQuoteStatus" default-entity-name="Quote" engine="simple"
- location="component://order/minilang/quote/QuoteServices.xml" invoke="checkUpdateQuoteStatus" auth="true">
+ <service name="checkUpdateQuoteStatus" default-entity-name="Quote" engine="groovy"
+ location="component://order/groovyScripts/quote/QuoteServices.groovy" invoke="checkUpdateQuoteStatus" auth="true">
<description>Set the Quote status to ordered.</description>
<auto-attributes include="pk" mode="IN" optional="false"/>
</service>
+
<!-- QuoteRole -->
<service name="createQuoteRole" default-entity-name="QuoteRole" engine="entity-auto" invoke="create" auth="true">
<description>Create a QuoteRole</description>
@@ -102,26 +103,26 @@ under the License.
<auto-attributes include="pk" mode="IN" optional="false"/>
</service>
<!-- QuoteItem -->
- <service name="createQuoteItem" default-entity-name="QuoteItem" engine="simple"
- location="component://order/minilang/quote/QuoteServices.xml" invoke="createQuoteItem" auth="true">
+ <service name="createQuoteItem" default-entity-name="QuoteItem" engine="groovy"
+ location="component://order/groovyScripts/quote/QuoteServices.groovy" invoke="createQuoteItem" auth="true">
<description>Create a QuoteItem</description>
<auto-attributes include="pk" mode="INOUT" optional="true"/>
<auto-attributes include="nonpk" mode="IN" optional="true"/>
</service>
- <service name="updateQuoteItem" default-entity-name="QuoteItem" engine="simple"
- location="component://order/minilang/quote/QuoteServices.xml" invoke="updateQuoteItem" auth="true">
+ <service name="updateQuoteItem" default-entity-name="QuoteItem" engine="groovy"
+ location="component://order/groovyScripts/quote/QuoteServices.groovy" invoke="updateQuoteItem" auth="true">
<description>Update a QuoteItem</description>
<auto-attributes include="pk" mode="IN" optional="true"/>
<auto-attributes include="nonpk" mode="IN" optional="true"/>
</service>
- <service name="removeQuoteItem" default-entity-name="QuoteItem" engine="simple"
- location="component://order/minilang/quote/QuoteServices.xml" invoke="removeQuoteItem" auth="true">
+ <service name="removeQuoteItem" default-entity-name="QuoteItem" engine="groovy"
+ location="component://order/groovyScripts/quote/QuoteServices.groovy" invoke="removeQuoteItem" auth="true">
<description>Remove a QuoteItem</description>
<auto-attributes include="pk" mode="INOUT" optional="true"/>
<auto-attributes include="nonpk" mode="IN" optional="true"/>
</service>
- <service name="copyQuoteItem" default-entity-name="QuoteItem" engine="simple"
- location="component://order/minilang/quote/QuoteServices.xml" invoke="copyQuoteItem" auth="true">
+ <service name="copyQuoteItem" default-entity-name="QuoteItem" engine="groovy"
+ location="component://order/groovyScripts/quote/QuoteServices.groovy" invoke="copyQuoteItem" auth="true">
<description>Copy a QuoteItem</description>
<auto-attributes include="pk" mode="IN" optional="false"/>
<auto-attributes include="nonpk" mode="IN" optional="true"/>
@@ -130,84 +131,98 @@ under the License.
<attribute name="copyQuoteAdjustments" type="String" mode="IN" optional="true"/>
</service>
<!-- QuoteAttribute -->
- <service name="createQuoteAttribute" default-entity-name="QuoteAttribute" engine="simple"
- location="component://order/minilang/quote/QuoteServices.xml" invoke="createQuoteAttribute" auth="true">
+ <service name="createQuoteAttribute" default-entity-name="QuoteAttribute" engine="entity-auto" invoke="create" auth="true">
<description>Create a QuoteAttribute</description>
+ <required-permissions join-type="AND">
+ <check-permission permission="ORDERMGR" action="_CREATE"/>
+ </required-permissions>
<auto-attributes include="pk" mode="IN" optional="false"/>
<auto-attributes include="nonpk" mode="IN" optional="true"/>
</service>
- <service name="updateQuoteAttribute" default-entity-name="QuoteAttribute" engine="simple"
- location="component://order/minilang/quote/QuoteServices.xml" invoke="updateQuoteAttribute" auth="true">
+ <service name="updateQuoteAttribute" default-entity-name="QuoteAttribute" engine="entity-auto" invoke="update" auth="true">
<description>Update a QuoteAttribute</description>
+ <required-permissions join-type="AND">
+ <check-permission permission="ORDERMGR" action="_UPDATE"/>
+ </required-permissions>
<auto-attributes include="pk" mode="IN" optional="true"/>
<auto-attributes include="nonpk" mode="IN" optional="true"/>
</service>
- <service name="removeQuoteAttribute" engine="simple" default-entity-name="QuoteAttribute"
- location="component://order/minilang/quote/QuoteServices.xml" invoke="removeQuoteAttribute" auth="true">
+ <service name="removeQuoteAttribute" default-entity-name="QuoteAttribute" engine="entity-auto" invoke="delete" auth="true">
<description>Remove a QuoteAttribute</description>
+ <required-permissions join-type="AND">
+ <check-permission permission="ORDERMGR" action="_DELETE"/>
+ </required-permissions>
<auto-attributes include="pk" mode="IN" optional="true"/>
<auto-attributes include="nonpk" mode="IN" optional="true"/>
</service>
<!-- QuoteCoefficient -->
- <service name="createQuoteCoefficient" default-entity-name="QuoteCoefficient" engine="simple"
- location="component://order/minilang/quote/QuoteServices.xml" invoke="createQuoteCoefficient" auth="true">
+ <service name="createQuoteCoefficient" default-entity-name="QuoteCoefficient" engine="entity-auto" invoke="create" auth="true">
<description>Create a QuoteCoefficient</description>
+ <required-permissions join-type="AND">
+ <check-permission permission="ORDERMGR" action="_CREATE"/>
+ </required-permissions>
<auto-attributes include="pk" mode="IN" optional="false"/>
<auto-attributes include="nonpk" mode="IN" optional="true"/>
</service>
- <service name="updateQuoteCoefficient" default-entity-name="QuoteCoefficient" engine="simple"
- location="component://order/minilang/quote/QuoteServices.xml" invoke="updateQuoteCoefficient" auth="true">
+ <service name="updateQuoteCoefficient" default-entity-name="QuoteCoefficient" engine="entity-auto" invoke="update" auth="true">
<description>Update a QuoteCoefficient</description>
+ <required-permissions join-type="AND">
+ <check-permission permission="ORDERMGR" action="_UPDATE"/>
+ </required-permissions>
<auto-attributes include="pk" mode="IN" optional="true"/>
<auto-attributes include="nonpk" mode="IN" optional="true"/>
</service>
- <service name="removeQuoteCoefficient" engine="simple" default-entity-name="QuoteCoefficient"
- location="component://order/minilang/quote/QuoteServices.xml" invoke="removeQuoteCoefficient" auth="true">
+ <service name="removeQuoteCoefficient" default-entity-name="QuoteCoefficient" engine="entity-auto" invoke="delete" auth="true">
<description>Remove a QuoteCoefficient</description>
+ <required-permissions join-type="AND">
+ <check-permission permission="ORDERMGR" action="_DELETE"/>
+ </required-permissions>
<auto-attributes include="pk" mode="IN" optional="true"/>
<auto-attributes include="nonpk" mode="IN" optional="true"/>
</service>
<!-- Specialized Quote services -->
- <service name="createQuoteAndQuoteItemForRequest" engine="simple" default-entity-name="QuoteItem"
- location="component://order/minilang/quote/QuoteServices.xml" invoke="createQuoteAndQuoteItemForRequest" auth="true">
+ <service name="createQuoteAndQuoteItemForRequest" engine="groovy" default-entity-name="QuoteItem"
+ location="component://order/groovyScripts/quote/QuoteServices.groovy" invoke="createQuoteAndQuoteItemForRequest" auth="true">
<description>Create a new Quote and Quote Item for a CustRequest</description>
<auto-attributes include="nonpk" mode="IN" optional="true"/>
<auto-attributes include="pk" mode="OUT" optional="true"/>
<override name="custRequestId" optional="false"/>
</service>
- <service name="autoUpdateQuotePrice" engine="simple" default-entity-name="QuoteItem"
- location="component://order/minilang/quote/QuoteServices.xml" invoke="autoUpdateQuotePrice" auth="true">
+ <service name="autoUpdateQuotePrice" engine="groovy" default-entity-name="QuoteItem"
+ location="component://order/groovyScripts/quote/QuoteServices.groovy" invoke="autoUpdateQuotePrice" auth="true">
<description>Update the QuoteItem price with the passed value (if present) or automatically from the averageCost</description>
<auto-attributes include="pk" mode="IN" optional="false"/>
<attribute name="manualQuoteUnitPrice" type="BigDecimal" mode="IN" optional="true"/>
<attribute name="defaultQuoteUnitPrice" type="BigDecimal" mode="IN" optional="true"/>
- <!--<attribute name="averageCost" type="BigDecimal" mode="IN" optional="true"/>
- <attribute name="costToPriceMult" type="BigDecimal" mode="IN" optional="true"/>-->
</service>
- <service name="autoCreateQuoteAdjustments" engine="simple" auth="true"
- location="component://order/minilang/quote/QuoteServices.xml" invoke="autoCreateQuoteAdjustments">
+ <service name="autoCreateQuoteAdjustments" engine="groovy" auth="true"
+ location="component://order/groovyScripts/quote/QuoteServices.groovy" invoke="autoCreateQuoteAdjustments">
<description>Remove all existing quote adjustments, recalc them and persist in QuoteAdjustment.</description>
<attribute name="quoteId" type="String" mode="IN" optional="false"/>
</service>
- <service name="createQuoteAdjustment" default-entity-name="QuoteAdjustment" engine="simple" auth="true"
- location="component://order/minilang/quote/QuoteServices.xml" invoke="createQuoteAdjustment">
+ <service name="createQuoteAdjustment" default-entity-name="QuoteAdjustment" engine="groovy" auth="true"
+ location="component://order/groovyScripts/quote/QuoteServices.groovy" invoke="createQuoteAdjustment">
<description>Creates a new quote adjustment record</description>
<auto-attributes mode="IN" include="nonpk" optional="true"/>
<auto-attributes mode="OUT" include="pk" optional="false"/>
<override name="quoteAdjustmentTypeId" optional="false"/>
<override name="quoteId" optional="false"/>
+ <override name="description" allow-html="any"/>
</service>
- <service name="updateQuoteAdjustment" default-entity-name="QuoteAdjustment" engine="simple"
- location="component://order/minilang/quote/QuoteServices.xml" invoke="updateQuoteAdjustment" auth="true">
+ <service name="updateQuoteAdjustment" default-entity-name="QuoteAdjustment" engine="entity-auto" invoke="update" auth="true">
<description>Update a QuoteAdjustment</description>
+ <required-permissions join-type="AND">
+ <check-permission permission="ORDERMGR" action="_UPDATE"/>
+ </required-permissions>
<auto-attributes include="pk" mode="IN" optional="true"/>
<auto-attributes include="nonpk" mode="IN" optional="true"/>
</service>
- <service name="removeQuoteAdjustment" engine="simple" default-entity-name="QuoteAdjustment"
- location="component://order/minilang/quote/QuoteServices.xml" invoke="removeQuoteAdjustment" auth="true">
+ <service name="removeQuoteAdjustment" default-entity-name="QuoteAdjustment" engine="entity-auto" invoke="delete" auth="true">
<description>Remove a QuoteAdjustment</description>
+ <required-permissions join-type="AND">
+ <check-permission permission="ORDERMGR" action="_DELETE"/>
+ </required-permissions>
<auto-attributes include="pk" mode="IN" optional="true"/>
- <auto-attributes include="nonpk" mode="IN" optional="true"/>
</service>
<!--Duplicate the service createQuoteWorkEffort, the first inform the deprecation, the second override and work normally-->
@@ -242,22 +257,22 @@ under the License.
<auto-attributes mode="IN" include="nonpk" optional="true"/>
<attribute name="quoteId" type="String" mode="IN"/>
</service>
- <service name="createQuoteFromCart" engine="simple" auth="true"
- location="component://order/minilang/quote/QuoteServices.xml" invoke="createQuoteFromCart">
+ <service name="createQuoteFromCart" engine="groovy" auth="true"
+ location="component://order/groovyScripts/quote/QuoteServices.groovy" invoke="createQuoteFromCart">
<description>Creates a new quote from a shopping cart</description>
<attribute name="cart" type="org.apache.ofbiz.order.shoppingcart.ShoppingCart" mode="IN" optional="false"/>
<attribute name="applyStorePromotions" type="String" mode="IN" optional="true"/>
<attribute name="quoteId" type="String" mode="OUT" optional="false"/>
</service>
- <service name="createQuoteFromShoppingList" engine="simple" auth="true"
- location="component://order/minilang/quote/QuoteServices.xml" invoke="createQuoteFromShoppingList">
+ <service name="createQuoteFromShoppingList" engine="groovy" auth="true"
+ location="component://order/groovyScripts/quote/QuoteServices.groovy" invoke="createQuoteFromShoppingList">
<description>Creates a new quote from a shopping list</description>
<attribute name="shoppingListId" type="String" mode="IN" optional="false"/>
<attribute name="applyStorePromotions" type="String" mode="IN" optional="true"/>
<attribute name="quoteId" type="String" mode="OUT" optional="false"/>
</service>
- <service name="createQuoteFromCustRequest" engine="simple" auth="true"
- location="component://order/minilang/quote/QuoteServices.xml" invoke="createQuoteFromCustRequest">
+ <service name="createQuoteFromCustRequest" engine="groovy" auth="true"
+ location="component://order/groovyScripts/quote/QuoteServices.groovy" invoke="createQuoteFromCustRequest">
<description>Creates a new quote from a customer request</description>
<attribute name="custRequestId" type="String" mode="IN" optional="false"/>
<attribute name="quoteTypeId" type="String" mode="IN" optional="true"/>
@@ -290,8 +305,8 @@ under the License.
<attribute name="quoteAdjustments" type="List" mode="IN" optional="true"/>
<attribute name="quoteId" type="String" mode="OUT" optional="false"/>
</service>
- <service name="createQuoteNote" engine="simple"
- location="component://order/minilang/quote/QuoteServices.xml" invoke="createQuoteNote" auth="true">
+ <service name="createQuoteNote" engine="groovy"
+ location="component://order/groovyScripts/quote/QuoteServices.groovy" invoke="createQuoteNote" auth="true">
<description>Create a note item and associate with a quote</description>
<attribute name="quoteId" type="String" mode="IN"/>
<attribute name="noteInfo" type="String" mode="IN" allow-html="any"/>
Copied: ofbiz/ofbiz-framework/trunk/applications/order/testdef/QuoteTests.xml (from r1849799, ofbiz/ofbiz-framework/trunk/applications/order/testdef/quotetests.xml)
URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/order/testdef/QuoteTests.xml?p2=ofbiz/ofbiz-framework/trunk/applications/order/testdef/QuoteTests.xml&p1=ofbiz/ofbiz-framework/trunk/applications/order/testdef/quotetests.xml&r1=1849799&r2=1849800&rev=1849800&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/order/testdef/quotetests.xml (original)
+++ ofbiz/ofbiz-framework/trunk/applications/order/testdef/QuoteTests.xml Thu Dec 27 14:40:03 2018
@@ -25,8 +25,9 @@ under the License.
<test-case case-name="loadQuoteTestData">
<entity-xml action="load" entity-xml-url="component://order/testdef/data/QuoteTestData.xml"/>
</test-case>
-
- <test-case case-name="quote-tests">
- <simple-method-test location="component://order/minilang/test/QuoteTests.xml"/>
+ <!-- <test-case case-name="quote-tests"> <simple-method-test location="component://order/minilang/test/QuoteTests.xml"/>
+ </test-case> -->
+ <test-case case-name="quoteTests">
+ <groovy-test-suite name="quoteTests" location="component://order/groovyScripts/test/QuoteTests.groovy"/>
</test-case>
</test-suite>
Modified: ofbiz/ofbiz-framework/trunk/applications/order/testdef/data/QuoteTestData.xml
URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/order/testdef/data/QuoteTestData.xml?rev=1849800&r1=1849799&r2=1849800&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/order/testdef/data/QuoteTestData.xml (original)
+++ ofbiz/ofbiz-framework/trunk/applications/order/testdef/data/QuoteTestData.xml Thu Dec 27 14:40:03 2018
@@ -20,6 +20,25 @@ under the License.
<entity-engine-xml>
<Quote quoteId="9000" quoteTypeId="PRODUCT_QUOTE" partyId="DemoCustomer" issueDate="2009-12-11 12:00:00.000" statusId="QUO_CREATED" currencyUomId="USD" productStoreId="9000" salesChannelEnumId="EMAIL_SALES_CHANNEL" validFromDate="2009-12-11 12:00:00.000" quoteName="Most competitive quote ever"/>
- <QuoteItem quoteId="9000" quoteItemSeqId="00001" productId="GZ-1001"/>
+ <QuoteItem quoteId="9000" quoteItemSeqId="00001" productId="GZ-1001" quantity="1"/>
+ <QuoteItem quoteId="9000" quoteItemSeqId="00002" productId="GZ-2644" quantity="1"/>
+ <QuoteItem quoteId="9000" quoteItemSeqId="00003" productId="GZ-1001" quantity="1"/>
<WorkEffort workEffortId="9007" workEffortTypeId="TASK" workEffortName="Quote WorkEffort"/>
+ <QuoteTerm quoteId="9000" quoteItemSeqId="00002" termTypeId="FIN_PAYMENT_DISC" termValue="10" termDays="5" uomId="CNY" description="Update test term"/>
+ <QuoteTerm quoteId="9000" quoteItemSeqId="00003" termTypeId="FIN_PAYMENT_DISC" termValue="5" termDays="7" uomId="CNY" description="Delete test term"/>
+ <Quote quoteId="9001" quoteTypeId="PRODUCT_QUOTE" partyId="DemoCustomer" issueDate="2009-12-11 12:00:00.000" statusId="QUO_CREATED" currencyUomId="USD" productStoreId="9000" salesChannelEnumId="EMAIL_SALES_CHANNEL" validFromDate="2009-12-11 12:00:00.000" quoteName="Most competitive quote ever"/>
+ <QuoteItem quoteId="9001" quoteItemSeqId="00001" productId="GZ-1005" quantity="1"/>
+ <QuoteAdjustment quoteAdjustmentId="9001" quoteId="9001" quoteItemSeqId="00001" quoteAdjustmentTypeId="SALES_TAX" amount="2"/>
+ <PartyAcctgPreference partyId="DemoCustomer" quoteSeqCustMethId="QUOTE_HOOK_ENF_SEQ"/>
+ <CustRequest custRequestId="9000" custRequestDate="2008-07-28 09:45:31.928" custRequestTypeId="RF_QUOTE" statusId="CRQ_SUBMITTED" fromPartyId="DemoCustomer" priority="9" custRequestName="Customer Request Usage" description="Demo CustRequest" productStoreId="9000"/>
+ <CustRequestItem custRequestId="9000" statusId="CRQ_SUBMITTED" custRequestItemSeqId="00001" productId="GZ-1001" story="This can be the longer story of an item on the customer request."/>
+ <ShoppingList shoppingListId="9000" shoppingListTypeId="SLT_WISH_LIST" productStoreId="9000" currencyUom="USD" isActive="Y" isPublic="N" listName="Test Shopping List" partyId="DemoCustomer"/>
+ <ShoppingListItem shoppingListId="9000" shoppingListItemSeqId="00001" productId="SV-1001" quantity="1.000000"/>
+ <ProductPromo productPromoId="9010" promoName="Test Percent off product set " promoText="20% off any one item, either GZ-1005 (.NIT Gizmo) or GZ-1006 (Open Gizmo) with a limit of 1 per order" userEntered="Y" showToCustomer="Y" requireCode="N" useLimitPerOrder="1" createdDate="2001-05-13 12:00:00.0" createdByUserLogin="admin" lastModifiedDate="2001-05-13 12:00:00.0" lastModifiedByUserLogin="admin"/>
+
+ <ProductPromoRule productPromoId="9010" productPromoRuleId="01" ruleName="Test Percent off rule"/><ProductPromoAction productPromoId="9010" productPromoRuleId="01" productPromoActionSeqId="01" productPromoActionEnumId="PROMO_PROD_DISC" orderAdjustmentTypeId="PROMOTION_ADJUSTMENT" quantity="1.0" amount="20.0"/>
+ <ProductPromoProduct productPromoId="9010" productPromoRuleId="01" productPromoActionSeqId="01" productPromoCondSeqId="_NA_" productId="GZ-1005" productPromoApplEnumId="PPPA_INCLUDE"/>
+ <ProductPromoProduct productPromoId="9010" productPromoRuleId="_NA_" productPromoActionSeqId="_NA_" productPromoCondSeqId="_NA_" productId="GZ-1006" productPromoApplEnumId="PPPA_INCLUDE"/>
+ <ProductStorePromoAppl productStoreId="9000" productPromoId="9010" fromDate="2001-05-13 12:00:00.0" sequenceNum="5"/>
+
</entity-engine-xml>
Modified: ofbiz/ofbiz-framework/trunk/applications/order/widget/ordermgr/QuoteWorkEffortForms.xml
URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/order/widget/ordermgr/QuoteWorkEffortForms.xml?rev=1849800&r1=1849799&r2=1849800&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/order/widget/ordermgr/QuoteWorkEffortForms.xml (original)
+++ ofbiz/ofbiz-framework/trunk/applications/order/widget/ordermgr/QuoteWorkEffortForms.xml Thu Dec 27 14:40:03 2018
@@ -47,7 +47,7 @@ under the License.
</field>
</form>
- <form name="AddQuoteWorkEffort" extends="EditWorkEffort" extends-resource="component://workeffort/widget/WorkEffortForms.xml" target="/ordermgr/control/ensureWorkEffortAndCreateQuoteWorkEffort" target-type="inter-app" title="" type="single"
+ <form name="AddQuoteWorkEffort" extends="EditWorkEffort" extends-resource="component://workeffort/widget/WorkEffortForms.xml" target="/ordermgr/control/createQuoteWorkEffort" target-type="inter-app" title="" type="single"
header-row-style="header-row" default-table-style="basic-table">
<field name="quoteId" map-name="parameters"><display/></field>