def update_orderitems(new_order, cart, update=False): """Update the order with all cart items, first removing all items if this is an update. """ if update: new_order.remove_all_items() else: # have to save first, or else we can't add orderitems new_order.site = cart.site new_order.save() # Add all the items in the cart to the order for item in cart.cartitem_set.all(): new_order_item = OrderItem(order=new_order, product=item.product, duration=item.duration) # unit_price=item.unit_price, # line_item_price=item.line_total) new_order_item.save() # Send a signal after copying items # External applications can copy their related objects using this satchmo_post_copy_item_to_order.send( cart, cartitem=item, order=new_order, orderitem=new_order_item ) new_order.recalculate_total()
def make_test_order(country, state): c = Contact(first_name="Gift", last_name="Tester", role=ContactRole.objects.get(pk='Customer'), email="*****@*****.**") c.save() if not isinstance(country, Country): country = Country.objects.get(iso2_code__iexact = country) ad = AddressBook(contact=c, description="home", street1 = "test", state=state, city="Portland", country = country, is_default_shipping=True, is_default_billing=True) ad.save() site = Site.objects.get_current() o = Order(contact=c, shipping_cost=Decimal('0.00'), site=site) o.save() p = Product.objects.get(slug='GIFT10') price = p.unit_price log.debug("creating with price: %s", price) item1 = OrderItem(order=o, product=p, quantity='2.0', unit_price=price, line_item_price=price*2) item1.save() detl = OrderItemDetail(name = 'email', value='*****@*****.**', sort_order=0, item=item1) detl.save() detl = OrderItemDetail(name = 'message', value='hello there', sort_order=0, item=item1) detl.save() return o
def make_test_order(country, state, site=None, orderitems=None): if not orderitems: orderitems = [ ('formaggio-fresco-di-carmasciano', 5), ] if not site: site = Site.objects.get_current() c = Contact(first_name="Order", last_name="Tester", role=ContactRole.objects.get(pk='Customer'), email="*****@*****.**") c.save() if not isinstance(country, Country): country = Country.objects.get(iso2_code__iexact = country) ad = AddressBook(contact=c, description="home", street1 = "via prova 123", state=state, city="Napoli", country = country, is_default_shipping=True, is_default_billing=True) ad.save() o = Order(contact=c, shipping_cost=Decimal('10.00'), site = site) o.save() for slug, qty in orderitems: p = Product.objects.get(slug=slug) price = p.unit_price item = OrderItem(order=o, product=p, quantity=qty, unit_price=price, line_item_price=price*qty) item.save() return o
def make_test_order(site, orderitems, shipping_cost='10.00', contact_info={}): default_contact_info = { 'first_name': "Order", 'last_name': "Tester", 'role': ContactRole.objects.get(pk='Customer'), 'email': "*****@*****.**", 'address': { 'description': 'home', 'street1': 'Via delle Chiaie 21', 'city': 'Napoli', 'state': 'NA', 'country': Country.objects.get(iso2_code__iexact='IT'), 'is_default_shipping': True, 'is_default_billing': True } } default_contact_info.update(contact_info) address_info = default_contact_info.pop('address') contact = Contact(**default_contact_info) contact.save() address_info['contact'] = contact address_book = AddressBook(**address_info) address_book.save() order = Order( contact=contact, shipping_cost=Decimal(shipping_cost), site = site ) order.save() for slug, quantity in orderitems: product = Product.objects.get(slug=slug) price = product.unit_price item = OrderItem( order=order, product=product, quantity=quantity, unit_price=price, line_item_price=price*quantity ) item.save() return order
def make_test_order(country, state): c = Contact(first_name="Gift", last_name="Tester", role=ContactRole.objects.get(pk='Customer'), email="*****@*****.**") c.save() if not isinstance(country, Country): country = Country.objects.get(iso2_code__iexact=country) ad = AddressBook(contact=c, description="home", street1="test", state=state, city="Portland", country=country, is_default_shipping=True, is_default_billing=True) ad.save() site = Site.objects.get_current() o = Order(contact=c, shipping_cost=Decimal('0.00'), site=site) o.save() p = Product.objects.get(slug='GIFT10') price = p.unit_price log.debug("creating with price: %s", price) item1 = OrderItem(order=o, product=p, quantity='2.0', unit_price=price, line_item_price=price * 2) item1.save() detl = OrderItemDetail(name='email', value='*****@*****.**', sort_order=0, item=item1) detl.save() detl = OrderItemDetail(name='message', value='hello there', sort_order=0, item=item1) detl.save() return o
def make_test_order(country, state, site=None, orderitems=None): if not orderitems: orderitems = [ ('formaggio-fresco-di-carmasciano', 5), ] if not site: site = Site.objects.get_current() c = Contact(first_name="Order", last_name="Tester", role=ContactRole.objects.get(pk='Customer'), email="*****@*****.**") c.save() if not isinstance(country, Country): country = Country.objects.get(iso2_code__iexact=country) ad = AddressBook(contact=c, description="home", street1="via prova 123", state=state, city="Napoli", country=country, is_default_shipping=True, is_default_billing=True) ad.save() o = Order(contact=c, shipping_cost=Decimal('10.00'), site=site) o.save() for slug, qty in orderitems: p = Product.objects.get(slug=slug) price = p.unit_price item = OrderItem(order=o, product=p, quantity=qty, unit_price=price, line_item_price=price * qty) item.save() return o
def make_test_order(site, orderitems, shipping_cost='10.00', contact_info={}): default_contact_info = { 'first_name': "Order", 'last_name': "Tester", 'role': ContactRole.objects.get(pk='Customer'), 'email': "*****@*****.**", 'address': { 'description': 'home', 'street1': 'Via delle Chiaie 21', 'city': 'Napoli', 'state': 'NA', 'country': Country.objects.get(iso2_code__iexact='IT'), 'is_default_shipping': True, 'is_default_billing': True } } default_contact_info.update(contact_info) address_info = default_contact_info.pop('address') contact = Contact(**default_contact_info) contact.save() address_info['contact'] = contact address_book = AddressBook(**address_info) address_book.save() order = Order(contact=contact, shipping_cost=Decimal(shipping_cost), site=site) order.save() for slug, quantity in orderitems: product = Product.objects.get(slug=slug) price = product.unit_price item = OrderItem(order=order, product=product, quantity=quantity, unit_price=price, line_item_price=price * quantity) item.save() return order
def cron_rebill(request=None): """Rebill customers with expiring recurring subscription products This can either be run via a url with GET key authentication or directly from a shell script. """ #TODO: support re-try billing for failed transactions if request is not None: if not config_value('PAYMENT', 'ALLOW_URL_REBILL'): return bad_or_missing(request, _("Feature is not enabled.")) if 'key' not in request.GET or request.GET['key'] != config_value('PAYMENT','CRON_KEY'): return HttpResponse("Authentication Key Required") expiring_subscriptions = OrderItem.objects.filter(expire_date__gte=timezone.now()).order_by('order', 'id', 'expire_date') for item in expiring_subscriptions: if item.product.is_subscription:#TODO - need to add support for products with trial but non-recurring if item.product.subscriptionproduct.recurring_times and item.product.subscriptionproduct.recurring_times + item.product.subscriptionproduct.get_trial_terms().count() == OrderItem.objects.filter(order=item.order, product=item.product).count(): continue if item.expire_date == datetime.date(timezone.now()) and item.completed: if item.id == OrderItem.objects.filter(product=item.product, order=item.order).order_by('-id')[0].id: #bill => add orderitem, recalculate total, porocess card new_order_item = OrderItem(order=item.order, product=item.product, quantity=item.quantity, unit_price=item.unit_price, line_item_price=item.line_item_price) #if product is recurring, set subscription end if item.product.subscriptionproduct.recurring: new_order_item.expire_date = item.product.subscriptionproduct.calc_expire_date() #check if product has 2 or more trial periods and if the last one paid was a trial or a regular payment. ordercount = item.order.orderitem_set.all().count() if item.product.subscriptionproduct.get_trial_terms().count() > 1 and item.unit_price == item.product.subscriptionproduct.get_trial_terms(ordercount - 1).price: new_order_item.unit_price = item.product.subscriptionproduct.get_trial.terms(ordercount).price new_order_item.line_item_price = new_order_item.quantity * new_order_item.unit_price new_order_item.expire_date = item.product.subscriptionproduct.get_trial_terms(ordercount).calc_expire_date() new_order_item.save() item.order.recalculate_total() # if new_order_item.product.subscriptionproduct.is_shippable == 3: # item.order.total = item.order.total - item.order.shipping_cost # item.order.save() payments = item.order.payments.all()[0] #list of ipn based payment modules. Include processors that use 3rd party recurring billing. ipn_based = ['PAYPAL'] if not payments.payment in ipn_based and item.order.balance > 0: #run card #Do the credit card processing here & if successful, execute the success_handler from livesettings import config_get_group payment_module = config_get_group('PAYMENT_%s' % payments.payment) credit_processor = payment_module.MODULE.load_module('processor') processor = credit_processor.PaymentProcessor(payment_module) processor.prepare_data(item.order) result = processor.process() if result.payment: reason_code = result.payment.reason_code else: reason_code = "unknown" log.info("""Processing %s recurring transaction with %s Order #%i Results=%s Response=%s Reason=%s""", payment_module.LABEL.value, payment_module.KEY.value, item.order.id, result.success, reason_code, result.message) if result.success: #success handler item.order.add_status(status='New', notes = ugettext("Subscription Renewal Order successfully submitted")) new_order_item.completed = True new_order_item.save() orderpayment = OrderPayment(order=item.order, amount=item.order.balance, payment=unicode(payment_module.KEY.value)) orderpayment.save() return HttpResponse()
def cron_rebill(request=None): """Rebill customers with expiring recurring subscription products This can either be run via a url with GET key authentication or directly from a shell script. """ #TODO: support re-try billing for failed transactions if request is not None: if not config_value('PAYMENT', 'ALLOW_URL_REBILL'): return bad_or_missing(request, _("Feature is not enabled.")) if 'key' not in request.GET or request.GET['key'] != config_value( 'PAYMENT', 'CRON_KEY'): return HttpResponse("Authentication Key Required") expiring_subscriptions = OrderItem.objects.filter( expire_date__gte=timezone.now()).order_by('order', 'id', 'expire_date') for item in expiring_subscriptions: if item.product.is_subscription: #TODO - need to add support for products with trial but non-recurring if item.product.subscriptionproduct.recurring_times and item.product.subscriptionproduct.recurring_times + item.product.subscriptionproduct.get_trial_terms( ).count() == OrderItem.objects.filter( order=item.order, product=item.product).count(): continue if item.expire_date == datetime.date( timezone.now()) and item.completed: if item.id == OrderItem.objects.filter( product=item.product, order=item.order).order_by('-id')[0].id: #bill => add orderitem, recalculate total, porocess card new_order_item = OrderItem( order=item.order, product=item.product, quantity=item.quantity, unit_price=item.unit_price, line_item_price=item.line_item_price) #if product is recurring, set subscription end if item.product.subscriptionproduct.recurring: new_order_item.expire_date = item.product.subscriptionproduct.calc_expire_date( ) #check if product has 2 or more trial periods and if the last one paid was a trial or a regular payment. ordercount = item.order.orderitem_set.all().count() if item.product.subscriptionproduct.get_trial_terms( ).count( ) > 1 and item.unit_price == item.product.subscriptionproduct.get_trial_terms( ordercount - 1).price: new_order_item.unit_price = item.product.subscriptionproduct.get_trial.terms( ordercount).price new_order_item.line_item_price = new_order_item.quantity * new_order_item.unit_price new_order_item.expire_date = item.product.subscriptionproduct.get_trial_terms( ordercount).calc_expire_date() new_order_item.save() item.order.recalculate_total() # if new_order_item.product.subscriptionproduct.is_shippable == 3: # item.order.total = item.order.total - item.order.shipping_cost # item.order.save() payments = item.order.payments.all()[0] #list of ipn based payment modules. Include processors that use 3rd party recurring billing. ipn_based = ['PAYPAL'] if not payments.payment in ipn_based and item.order.balance > 0: #run card #Do the credit card processing here & if successful, execute the success_handler payment_module = config_get_group('PAYMENT_%s' % payments.payment) credit_processor = payment_module.MODULE.load_module( 'processor') processor = credit_processor.PaymentProcessor( payment_module) processor.prepare_data(item.order) result = processor.process() if result.payment: reason_code = result.payment.reason_code else: reason_code = "unknown" log.info( """Processing %s recurring transaction with %s Order #%i Results=%s Response=%s Reason=%s""", payment_module.LABEL.value, payment_module.KEY.value, item.order.id, result.success, reason_code, result.message) if result.success: #success handler item.order.add_status( status='New', notes=ugettext( "Subscription Renewal Order successfully submitted" )) new_order_item.completed = True new_order_item.save() orderpayment = OrderPayment( order=item.order, amount=item.order.balance, payment=six.text_type( payment_module.KEY.value)) orderpayment.save() return HttpResponse()
def import_order_items(): idx = 0 chunk = 2000 total = ContactOrderitem.objects.all().count() # old_items = ContactOrderitem.objects.filter(order__id__gte=15014).iterator() # old_items = ContactOrderitem.objects.filter(contactorderitemdetail__name='date', contactorderitemdetail__value='01-06-2010') # old_items = ContactOrderitem.objects.filter(contactorderitemdetail__name__in=('REFUND', 'VOID', 'transmutation')) while idx < total: print '*'*75, idx old_items = ContactOrderitem.objects.all().order_by('id')[idx:idx+chunk] idx += chunk for old_item in old_items: # TODO old_items have a boolean called insurance? is this satchmo or custom and is it necessary? details_dict = {} details = old_item.contactorderitemdetail_set.all().iterator() for d in details: details_dict[d.name] = d.value if 'date' not in details_dict or details_dict['date'] == '77-77-7777': day = date(2009, 1, 1) else: d, month, year = map(int, details_dict['date'].split('-')) if year < 15: year = year + 2000 try: day = date(year, month, d) except Exception, e: print details_dict from IPython.Shell import IPShellEmbed; IPShellEmbed()() # Quantity, sample: 'quantity_Children (12 and under)::0__quantity_Senior (65+)::3__quantity_Adults::2' # Quantity, sample: 'quantity_default::2' # quantity_Senior (65+)::0__quantity_Children (12 and under) (with Aquarium)::0__quantity_Adults::4__quantity_Children (12 and under)::2__quantity_Senior (65+) (with aquarium)::0__quantity_Adults (with Aquarium)::0 # print old_item.quantity children = seniors = adults = default = 0 raw_quantities = old_item.quantity.split('__') for raw_q in raw_quantities: quan = Decimal(raw_q.split('::')[-1]) if 'Children' in raw_q: children += quan if 'Senior' in raw_q: seniors += quan if 'Adults' in raw_q: adults += quan if 'default' in raw_q: default += quan options = { 'Adult': adults + default, 'Senior': seniors, 'Child': children } # print 'Adults: %(Adult)d Senior: %(Senior)d Child: %(Child)d' % options # sleep(1) # continue order = Order.objects.get(id=old_item.order.id) for key, quantity in options.items(): if quantity == 0: continue # so if this product is actually a multiproduct, we need to create items for both products tour_types = get_tour_types_for_old_id(int(old_item.product_id)) for tour_type in tour_types: tour_time = None if 'time' not in details_dict or details_dict['time'] == '-1': # Probably a multiproduct: if is_multiproduct(int(old_item.product_id)): old_product = ProductProduct.objects.get(id=int(old_item.product_id)) dts2s = ProductDatetimeschema2.objects.filter(product=old_product) for dts2 in dts2s: if dts2.dts.product.id == tour_type.old_product_id: tour_time = dts2.dts.get_nice_data()[0] else: tour_time, days = ProductDatetimeschema.objects.get(id=details_dict['time']).get_nice_data() if tour_time is None: if int(old_item.product_id) == 8: # move on, this is a gift certificate continue else: if int(old_item.product_id) == 4: print 'Houston, we have a problem' from IPython.Shell import IPShellEmbed; IPShellEmbed()() continue tour_product = tour_type.get_product(day, tour_time=tour_time) new_item = OrderItem(order=order) new_item.quantity = quantity # These don't have product variations if tour_type.id in (6, 7, 8): new_item.product = tour_product.product else: try: new_item.product = tour_product.product.configurableproduct.productvariation_set.get(options__value=key).product except: print 'uhh' from IPython.Shell import IPShellEmbed; IPShellEmbed()() new_item.tax = 0 new_item.unit_tax = 0 new_item.line_item_price = old_item.unit_price * int(quantity) new_item.unit_price = old_item.unit_price try: new_item.full_clean() except ValidationError, e: print 'full_clean' from IPython.Shell import IPShellEmbed; IPShellEmbed()() assert False new_item.save() # Handle VOID, REFUND, and transmutation if 'VOID' in details_dict: adjustment = Adjustment(item=new_item) adjustment.status = Adjustment.VOIDED adjustment.save() print details_dict elif 'REFUND' in details_dict: adjustment = Adjustment(item=new_item) adjustment.status = Adjustment.VOIDED adjustment.save() print details_dict elif 'transmutation' in details_dict: # Don't think there were any of these from IPython.Shell import IPShellEmbed; IPShellEmbed()() else: # update inventory product = tour_product.product product.total_sold = Decimal(product.total_sold) + Decimal(quantity) product.save() print 'Saved OrderItem: ', new_item.id, ' Order #', order.id if 'CODE' in details_dict and details_dict['CODE']: try: reseller = Reseller.objects.get(code=details_dict['CODE']) reseller.orders.add(order) reseller.save() # print 'Matched order ', order.id, ' and reseller ', reseller.company_name except Reseller.DoesNotExist: try: concierge = Concierge.objects.get(code=details_dict['CODE']) concierge.orders.add(order) concierge.save() print 'Matched order ', order.id, ' and reseller ', concierge.name except Concierge.DoesNotExist: print 'No reseller/concierge for code: ', details_dict['CODE']