def test_init(self): """ The constructor should pull initial data from the passed-in instance. """ enterprise_offer = factories.EnterpriseOfferFactory() ecm = EnterpriseContractMetadata( discount_value=25, discount_type=EnterpriseContractMetadata.PERCENTAGE, amount_paid=12345 ) enterprise_offer.enterprise_contract_metadata = ecm enterprise_offer.max_global_applications = 2 enterprise_offer.max_discount = 300 form = EnterpriseOfferForm(instance=enterprise_offer) self.assertEqual( uuid.UUID(form['enterprise_customer_uuid'].value()), enterprise_offer.condition.enterprise_customer_uuid ) self.assertEqual( uuid.UUID(form['enterprise_customer_catalog_uuid'].value()), enterprise_offer.condition.enterprise_customer_catalog_uuid ) self.assertEqual(form['benefit_type'].value(), enterprise_offer.benefit.proxy().benefit_class_type) self.assertEqual(form['benefit_value'].value(), enterprise_offer.benefit.value) self.assertEqual(form['contract_discount_type'].value(), EnterpriseContractMetadata.PERCENTAGE) self.assertEqual(form['contract_discount_value'].value(), 25) self.assertEqual(form['prepaid_invoice_amount'].value(), 12345) self.assertEqual(form['max_global_applications'].value(), 2) self.assertEqual(form['max_discount'].value(), 300)
def test_save_edit(self): """ Previously-created ConditionalOffer, Benefit, and Condition instances should be updated. """ offer = factories.EnterpriseOfferFactory() ecm = EnterpriseContractMetadata( discount_value=self.contract_discount_value, discount_type=self.contract_discount_type, amount_paid=self.prepaid_invoice_amount, ) offer.enterprise_contract_metadata = ecm data = self.generate_data( enterprise_customer_uuid=offer.condition.enterprise_customer_uuid, benefit_type=Benefit.FIXED) self.mock_specific_enterprise_customer_api( data['enterprise_customer_uuid']) form = EnterpriseOfferForm(request=self.request, data=data, instance=offer) form.is_valid() form.save() offer.refresh_from_db() self.assert_enterprise_offer_conditions( offer, data['enterprise_customer_uuid'], data['enterprise_customer_name'], data['enterprise_customer_catalog_uuid'], data['benefit_value'], data['benefit_type'], 'Discount of type {} provided by {} for {}.'.format( ConditionalOffer.SITE, data['enterprise_customer_name'][:48], data['enterprise_customer_catalog_uuid']), data['contract_discount_type'], data['contract_discount_value'], data['prepaid_invoice_amount'], )
def _get_contract_metadata_for_manual_order(discount_percentage): """ Return the EnterpriseContractMetadata object for manual order by inserting the given discount percentage. """ return EnterpriseContractMetadata( discount_value=discount_percentage, discount_type=EnterpriseContractMetadata.PERCENTAGE)
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 test_calculate_effective_discount_percentage_percentage(self): """ Test correct values for discount percentage are evaluated when discount type is PERCENTAGE. """ enterprise_contract_metadata = EnterpriseContractMetadata( discount_type=EnterpriseContractMetadata.PERCENTAGE, discount_value=Decimal('12.3456'), amount_paid=Decimal('12000.00')) # pylint: disable=protected-access actual = EnterpriseDiscountMixin._calculate_effective_discount_percentage( enterprise_contract_metadata) expected = Decimal('.123456') self.assertEqual(actual, expected)
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)
def setUp(self): super(EnterpriseContractMetadataTests, self).setUp() self.ecm = EnterpriseContractMetadata()
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()