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> |
Free forum by Nabble | Edit this page |