def attach_or_update_contract_metadata_on_coupon(coupon, **update_kwargs): """ Creates a enterprise_contract_metadata object and assigns it as an attr of the coupon product if it does not exist. If enterprise_contract_metadata attr exists, uses kwargs provided to update the existing object. Expected kwargs based on model: contract_discount_type, contract_discount_value, prepaid_invoice_amount """ try: contract_metadata = coupon.attr.enterprise_contract_metadata except AttributeError: contract_metadata = EnterpriseContractMetadata() coupon.attr.enterprise_contract_metadata = contract_metadata for key, value in update_kwargs.items(): logger.info( 'Setting attribute [%s] to [%s] on contract_metadata for coupon [%s]', key, value, coupon.id) setattr(contract_metadata, key, value) contract_metadata.clean() contract_metadata.save() coupon.save()
def save(self, commit=True): enterprise_customer_uuid = self.cleaned_data[ 'enterprise_customer_uuid'] enterprise_customer_catalog_uuid = self.cleaned_data[ 'enterprise_customer_catalog_uuid'] sales_force_id = self.cleaned_data['sales_force_id'] site = self.request.site contract_discount_value = self.cleaned_data['contract_discount_value'] contract_discount_type = self.cleaned_data['contract_discount_type'] prepaid_invoice_amount = self.cleaned_data['prepaid_invoice_amount'] enterprise_customer = get_enterprise_customer( site, enterprise_customer_uuid) enterprise_customer_name = enterprise_customer['name'] # Note: the actual name is not displayed like this in the template, so it's safe to use the UUID here. # And in fact we have to, because otherwise we face integrity errors since Oscar forces this name to be unique. # Truncate 'enterprise_customer_name' to 48 characters so that our complete name with # format 'Discount of type {site} provided by {enterprise_name} for {catalog_uuid}. does # not exceed the limit of 128 characters for Oscar's 'AbstractConditionalOffer' name. offer_name = _(u'Discount of type {} provided by {} for {}.'.format( ConditionalOffer.SITE, enterprise_customer_name[:48], # pylint: disable=unsubscriptable-object, enterprise_customer_catalog_uuid)) self.instance.name = offer_name self.instance.status = ConditionalOffer.OPEN self.instance.offer_type = ConditionalOffer.SITE self.instance.max_basket_applications = 1 self.instance.partner = site.siteconfiguration.partner self.instance.priority = OFFER_PRIORITY_ENTERPRISE self.instance.sales_force_id = sales_force_id self.instance.max_global_applications = self.cleaned_data.get( 'max_global_applications') self.instance.max_discount = self.cleaned_data.get('max_discount') self.instance.max_user_applications = self.cleaned_data.get( 'max_user_applications') self.instance.max_user_discount = self.cleaned_data.get( 'max_user_discount') if commit: ecm = self.instance.enterprise_contract_metadata if ecm is None: ecm = EnterpriseContractMetadata() ecm.discount_value = contract_discount_value ecm.discount_type = contract_discount_type ecm.amount_paid = prepaid_invoice_amount ecm.clean() ecm.save() self.instance.enterprise_contract_metadata = ecm benefit = getattr(self.instance, 'benefit', Benefit()) benefit.proxy_class = class_path( BENEFIT_MAP[self.cleaned_data['benefit_type']]) benefit.value = self.cleaned_data['benefit_value'] benefit.save() self.instance.benefit = benefit if hasattr(self.instance, 'condition'): self.instance.condition.enterprise_customer_uuid = enterprise_customer_uuid self.instance.condition.enterprise_customer_name = enterprise_customer_name self.instance.condition.enterprise_customer_catalog_uuid = enterprise_customer_catalog_uuid self.instance.condition.save() else: self.instance.condition = create_condition( EnterpriseCustomerCondition, enterprise_customer_uuid=enterprise_customer_uuid, enterprise_customer_name=enterprise_customer_name, enterprise_customer_catalog_uuid= enterprise_customer_catalog_uuid, ) return super(EnterpriseOfferForm, self).save(commit)
class EnterpriseContractMetadataTests(TestCase): def setUp(self): super(EnterpriseContractMetadataTests, self).setUp() self.ecm = EnterpriseContractMetadata() def test_validate_fixed_value_good(self): """ Verify expected good values do not throw errors on clean. """ self.ecm.discount_type = EnterpriseContractMetadata.FIXED good_values = [ '1234567890', '1234567890.23', '10000', '.45', ] for value in good_values: self.ecm.discount_value = value self.ecm.clean() def test_validate_fixed_value_bad(self): """ Verify expected bad values throw errors on clean. """ self.ecm.discount_type = EnterpriseContractMetadata.FIXED bad_values = [ '12345678901', '12345678901.23', '.2345', '123.456', ] for value in bad_values: self.ecm.discount_value = value with self.assertRaises(ValidationError): self.ecm.clean() def test_validate_percentage_value_good(self): """ Verify expected good values do not throw errors on clean. """ self.ecm.discount_type = EnterpriseContractMetadata.PERCENTAGE good_values = [ '10.12345', '95', '12.1', '100', '100.00000', ] for value in good_values: self.ecm.discount_value = value self.ecm.clean() def test_validate_percentage_value_bad(self): """ Verify expected bad values throw errors on clean. """ self.ecm.discount_type = EnterpriseContractMetadata.PERCENTAGE bad_values = [ '145123', '100.01', ] for value in bad_values: self.ecm.discount_value = value with self.assertRaises(ValidationError): self.ecm.clean()