def payment_should_be_skipped(order_id): if config.SKIP_PAYMENT: return True if config.ENABLE_MAGIC_CREDIT_CARD: try: def normalize_name(name): return ' '.join(name.split()).lower() magic_credit_card = json.loads(config.MAGIC_CREDIT_CARD_JSON) magic_brand = magic_credit_card['brand'] magic_country = magic_credit_card['country'] magic_exp_month = magic_credit_card['exp_month'] magic_exp_year = magic_credit_card['exp_year'] magic_last4 = magic_credit_card['last4'] magic_name = normalize_name(magic_credit_card['name']) user_credit_card = get_credit_card(get_order(order_id).user_id) return magic_brand == user_credit_card['brand'] and \ magic_country == user_credit_card['country'] and \ magic_exp_month == user_credit_card['exp_month'] and \ magic_exp_year == user_credit_card['exp_year'] and \ magic_last4 == user_credit_card['last4'] and \ magic_name == normalize_name(user_credit_card['name']) except: logging.exception( 'Failed to compare user\'s credit card to MAGIC_CREDIT_CARD_JSON' ) return False return False
def create_product_offers(order_id, products_list): order = get_order(order_id) products = products_list[0] master_product_id = products[0]['master_product_id'] master_product = get_master_product(master_product_id) source = db.session.query(Source).filter_by(id=master_product.source_id).first() product_offer = ProductOffer( order_id=order_id, source_id=master_product.source_id, wine_type=order.subscription.type, priority=1, name=source.name, accepted=True ) db.session.add(product_offer) db.session.flush() for product in products: create_offer_item_from_dict(product, product_offer.id) db.session.flush() populate_offer_costs(product_offer)
def get_user_order_data(order_id): order = get_order(order_id) tracking_url = get_order_tracking_url(order) user = order.user shipping_address = { 'name': user.first_name or '', 'city': order.shipping_city, 'street': order.shipping_street1, 'state': USA_STATES_POSTCODE[order.shipping_state_region], 'zipcode': order.shipping_postcode, 'email': user.email, 'phone': user.phone, } product_offer = order.accepted_offers[0] products = [] for product in product_offer.offer_items: products.append({ 'name': product.name, 'price': str(product.price), 'sku': product.sku or '', }) carrier = '' if order.shipping_method: carrier = order.shipping_method.carrier.carrier return { 'order': { 'url': 'url', 'number': order.order_number, 'month': MONTH[order.month - 1], 'tracking_number': order.shipping_tracking_num, 'tracking_url': tracking_url or '', 'shipping_date': str(order.shipping_date), 'carrier': carrier, 'deeplink': '%s/subscriptions/?id=%s' % (config.SERVER_DEEPLINK_URL, order_id), }, 'billing_address': shipping_address, 'shipping_address': shipping_address, 'products': products, 'total_cost': str(product_offer.total_cost), 'product_cost': str(product_offer.product_cost), 'salestax_cost': str(product_offer.salestax_cost), 'shipping_cost': str(product_offer.shipping_cost), 'source_name': product_offer.source.name, }
def run(self, order_id): logging.info('running SearchAction') order = get_order(order_id) themes = get_user_themes(order.user_id) subscription = order.subscription bottle_qty = subscription.bottle_qty wine_types = get_wine_types(subscription.type) budget = subscription.budget address = order.user.primary_user_address order.shipping_name = order.user.first_name order.shipping_street1 = address.street1 order.shipping_street2 = address.street2 order.shipping_state_region = address.state_region order.shipping_country = address.country order.shipping_city = address.city order.shipping_postcode = address.postcode order.shipping_phone = order.user.phone order.subscription_snapshot.type = subscription.type order.subscription_snapshot.bottle_qty = bottle_qty order.subscription_snapshot.budget = budget db.session.flush() user_id = order.user.id user_state_region = order.user.primary_user_address.state_region state_postal_code = state_to_postcode(user_state_region) sources = get_sources_shipping_to(state_postal_code) if not sources: raise OrderException( 'No source found that ships to User: %s in state_region: %s' % (user_id, user_state_region) ) sources_budget = get_sources_budget(sources, budget, bottle_qty, order.shipping_postcode) if not sources_budget: raise OrderException('No available shipping or tax info') sent_wines = get_all_accepted_wines(user_id) # call search API products = do_search(bottle_qty, wine_types, themes, sources_budget, sent_wines) logging.info('got products: %s', products) # update DB delete_product_offers(order_id) db.session.flush() create_product_offers(order_id, products) if order.scheduled_for is None: subscription.last_order_searched_at = datetime.utcnow() else: subscription.last_order_searched_at = order.scheduled_for return NOTIFY_WINE_EXPERT_ACTION, READY_TO_PROPOSE_STATE
def run(self, order_id): logging.info('running NotifyUserShippedAction for order: %s', order_id) order = get_order(order_id) # device_tokens = [t.token for t in order.user.device_tokens] # msg = 'Your order is shipped!' # send_push(device_tokens, msg, order_id=order_id) try: self._send_email(order.id) except Exception as e: logging.exception('Error when sending shipping email: %s', e) return None, USER_NOTIFIED_SHIPPED_STATE
def authorize_payment(order_id): logging.info('authorizing payment for order: %s', order_id) order = get_order(order_id) customer = get_stripe_customer(order.user.stripe_customer_id) offer = get_accepted_product_offer(order_id) charge = stripe.Charge.create(amount=int(offer.total_cost * 100), currency='usd', customer=customer.id, capture=False) offer.stripe_charge_id = charge.id db.session.commit()
def run(self, order_id): logging.info('running CompleteAction order_id: %s', order_id) order = get_order(order_id) utcnow = datetime.utcnow() if order.user.primary_user_subscription.last_order_searched_at is None: scheduled_for = utcnow else: scheduled_for = order.user.primary_user_subscription.last_order_searched_at scheduled_for += relativedelta(months=1) if scheduled_for < utcnow: scheduled_for = utcnow create_order(order.user.id, order.user.primary_user_subscription.id, scheduled_for=scheduled_for) return None, COMPLETED_STATE
def run(self, order_id): logging.info('running NotifyExceptionAction order_id: %s', order_id) try: expert = get_wine_expert_for_order(order_id) order = get_order(order_id) new_state = EXCEPTION_STATE_NOTIFY_MAPPING.get( order.state, EXCEPTION_STATE) subject = 'Exception in Order: %s' % order.id send_mail(expert.email, subject, order.exception_message) except Exception: logging.exception( 'Exception in NotifyExceptionAction for order: %s', order_id) return None, EXCEPTION_TO_NOTIFY_STATE return None, new_state
def mutate_and_get_payload(cls, root, info, **inp): logging.info('SaveOrder input: %s', inp) order_id = from_global_id_assert_type(inp['id'], 'Order') order = OrderModel.query.get(order_id) save_input_fields(inp, ( 'shipping_name', 'shipping_street1', 'shipping_street2', 'shipping_city', 'shipping_country', 'shipping_state_region', 'shipping_postcode', 'shipping_phone', 'shipping_tracking_num', 'shipping_date', ), order) try: shipping_method_global_id = inp['shipping_method_id'] except KeyError: pass else: order.shipping_method_id = from_global_id_assert_type( shipping_method_global_id, 'OrderShippingMethod') save_product_offers(inp, order) replace_offer_items(inp, order) db.session.commit() order_action = inp.get('action') if order_action: task_res = run_order.delay(order.id, action=order_action) try: # wait for the task for up to 10 seconds (some order actions are quick) task_res.wait(timeout=10) except TimeoutError: pass db.session.expire_all() return SaveOrder(order=get_order(order.id))
def run(self, order_id): logging.info('running NotifyUserAction for order: %s', order_id) order = get_order(order_id) # device_tokens = [t.token for t in order.user.device_tokens] month = get_order_creation_month(order) # msg = f'Your {month} wine selections are available! Please confirm quickly to ensure availability.' # send_push(device_tokens, msg) try: send_template_email( order.user.email, 'search_completed', { 'month': month, 'deeplink': config.SHIPMENTS_DEEPLINK_URL # Goes to webui # 'deeplink': config.SERVER_DEEPLINK_URL + '/subscriptions/', }) except Exception as e: logging.exception('Error when sending search_completed mail: %s', e) return None, PROPOSED_TO_USER_STATE
def __init__(self, order_or_id): if isinstance(order_or_id, Order): self.order = order_or_id else: self.order = get_order(order_or_id)
def run(self, order_id): logging.info('running RetrySearchAction order_id: %s', order_id) get_order(order_id).scheduled_for = datetime.utcnow() return SEARCH_ACTION, STARTED_STATE