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 mutate_and_get_payload(cls, root, info, **inp): logging.info('RunPipelineSequence input: %s', inp) pipeline_sequence_id = from_global_id_assert_type( inp['id'], 'PipelineSequence') source_id = db.session.query(PipelineSequenceModel.source_id).filter( PipelineSequenceModel.id == pipeline_sequence_id).first()[0] _run_pipeline_sequence_full(source_id) return RunPipelineSequence(pipeline_sequence=PipelineSequenceModel. query.get(pipeline_sequence_id))
def mutate_and_get_payload(cls, root, info, **inp): logging.info('SavePipelineSequence input: %s', inp) pipeline_sequence_id = from_global_id_assert_type( inp['id'], 'PipelineSequence') save_input_fields( inp, (('is_full_active', 'is_active'), ), # TODO support is_update_active as well when it is available in m3-integration PipelineSequenceModel.query.get(pipeline_sequence_id), ) db.session.commit() return SavePipelineSequence(pipeline_sequence=PipelineSequenceModel. query.get(pipeline_sequence_id))
def mutate_and_get_payload(cls, root, info, identity, offer_id=None): logging.info('acceptOffer offer_id: %s', offer_id) offer_id = from_global_id_assert_type(offer_id, 'ProductOffer') offer = ProductOfferModel.query.get(offer_id) order_id = offer.order_id # Check permissions if identity.id.subject != offer.order.user.cognito_sub: raise Exception('PermissionDenied') offer.accepted = True db.session.commit() # Lock money run_order(order_id, ACCEPT_ACTION) return AcceptProductOffer()
def save_user_cards(inp, user): cards_inp = inp.get('user_cards') if cards_inp is None: return card_inp_dict = {} for card_inp in cards_inp: domain_card_id = from_global_id_assert_type(card_inp.domain_card_id, 'DomainCard') if domain_card_id in card_inp_dict: raise ValueError('UserCard.domainCardId: duplicate entry for ' + repr(card_inp.domain_card_id)) card_inp_dict[domain_card_id] = card_inp domain_cards = DomainCardModel.query.filter(DomainCardModel.id.in_(card_inp_dict.keys())) domain_card_dict = {domain_card.id: domain_card for domain_card in domain_cards} existing_user_cards = UserCardModel.query.filter( UserCardModel.user_id == user.id ).filter(UserCardModel.card_id.in_(card_inp_dict.keys())) existing_user_card_dict = {} for user_card in existing_user_cards: try: duplicated_user_card = existing_user_card_dict[user_card.card_id] except KeyError: existing_user_card_dict[user_card.card_id] = user_card else: current_app.logger.warning( "Duplicate user card found in the database. Deleting..." " (user id=%(user_id)d; domain card id=%(domain_card_id)d;" " user card id being deleted=%(deleted_user_card_id)d;" " user card id that will be used instead=%(user_card_id)d)", { 'user_id': user.id, 'domain_card_id': user_card.card_id, 'deleted_user_card_id': user_card.id, 'user_card_id': duplicated_user_card.id, } ) db.session.delete(user_card) _add_update_user_cards(card_inp_dict, domain_card_dict, existing_user_card_dict, user)
def save_product_offers(order_inp, order): offers_inp = order_inp.get('product_offers') if offers_inp is None: return offer_inp_dict = {} for offer_inp in offers_inp: product_offer_id = from_global_id_assert_type(offer_inp.id, 'ProductOffer') offer_inp_dict[product_offer_id] = offer_inp product_offers = ProductOfferModel.query.filter( ProductOfferModel.order_id == order.id, ProductOfferModel.id.in_(offer_inp_dict.keys())) for product_offer in product_offers: offer_inp = offer_inp_dict[product_offer.id] expert_note = offer_inp.get('expert_note') if expert_note is not None: product_offer.expert_note = expert_note costs_updated = False salestax_cost_str = offer_inp.get('salestax_cost') if salestax_cost_str is not None: salestax_cost = Decimal(salestax_cost_str) if salestax_cost != product_offer.salestax_cost: product_offer.salestax_cost = salestax_cost costs_updated = True shipping_cost_str = offer_inp.get('shipping_cost') if shipping_cost_str is not None: shipping_cost = Decimal(shipping_cost_str) if shipping_cost != product_offer.shipping_cost: product_offer.shipping_cost = shipping_cost costs_updated = True if costs_updated: product_offer.total_cost, product_offer.product_cost = recalc_total_cost( product_offer.offer_items, product_offer.salestax_cost, product_offer.shipping_cost)
def mutate_and_get_payload(cls, root, info, **inp): logging.info('SavePipelineSchedules input: %s', inp) schedule_inp_dict = {} for schedule_inp in inp['pipeline_schedules']: schedule_id = from_global_id_assert_type(schedule_inp['id'], 'PipelineSequence') schedule_inp_dict[schedule_id] = schedule_inp for schedule in fetch_schedules_by_ids(schedule_inp_dict.keys()): schedule_inp = schedule_inp_dict[schedule.id] save_input_fields( schedule_inp, (('is_full_active', 'is_active'), ), # TODO support is_update_active as well when it is available in m3-integration schedule, ) db.session.commit() return SavePipelineSchedules(pipeline_schedules=fetch_schedules_by_ids( schedule_inp_dict.keys()))
def mutate_and_get_payload(cls, root, info, identity, **inp): logging.info('saveUser mutation input: %s', inp) try: global_id = inp['id'] except KeyError: user = get_or_create_user(identity.id.subject) is_user_new = not user.registration_finished else: user_id = from_global_id_assert_type(global_id, 'User') user = get_user(user_id) is_user_new = False if user.cognito_sub == identity.id.subject: is_admin_user = admin_user_permission.can() else: admin_user_permission.test(http_exception=401) is_admin_user = True old_firstname = user.first_name or '' old_lastname = user.last_name or '' old_username = user.username or '' save_input_fields( inp, ( 'first_name', 'last_name', 'username', 'avatar', ), user ) new_firstname = user.first_name or '' new_lastname = user.last_name or '' new_username = user.username or '' if new_username != old_username: # TODO otereshchenko: make sure invalid characters are escaped in manual usernames as well user.username_set_manually = True if new_firstname != old_firstname or new_lastname != old_lastname: populate_automatic_username(user) # Save address save_input_subfields( inp, 'user_address', ( 'country', 'state_region', 'city', 'street1', 'street2', 'postcode', ), user, lambda: UserAddressModel(user_id=user.id), model_attr='primary_user_address' ) # Save subscription subscription_inp = inp.get('user_subscription') if subscription_inp is not None: subscription_inp.produce_budget_decimal() subscription = save_subscription(user.id, subscription_inp) user.primary_user_subscription_id = subscription.id # Save device_token device_token_inp = inp.get('device_token') if device_token_inp is not None: save_device_token(user.id, device_token_inp) # Save Stripe customer id stripe_token = inp.get('stripe_token') if stripe_token is not None: save_stripe_customer_id(user.id, stripe_token) save_user_cards(inp, user) if is_admin_user: cognito_user_sync = CognitoUserSync(username=user.cognito_sub) else: cognito_user_sync = CognitoUserSync(access_token=identity.id.encoded_token) cognito_updated = False if is_admin_user or not is_user_new: cognito_updated = save_cognito_user(cognito_user_sync, inp) if cognito_updated or is_user_new: try: update_user_from_cognito( cognito_user_sync=cognito_user_sync, user=user, clear_missing_data=False ) except: logging.exception( 'Failed to synchronize a user with id=%s from Cognito to DB!', user.id ) if is_user_new and user.first_name: user.registration_finished = True db.session.commit() return SaveUser(user=user)
def replace_offer_items(order_inp, order): replacements_inp = order_inp.get('offer_item_replacements') if replacements_inp is None: return replacement_inp_dict = {} for replacement_inp in replacements_inp: offer_item_id = from_global_id_assert_type( replacement_inp.offer_item_id, 'OfferItem') replacement_inp_dict[offer_item_id] = replacement_inp offer_items = OfferItemModel.query.join( OfferItemModel.product_offer).filter( ProductOfferModel.order_id == order.id, OfferItemModel.id.in_(replacement_inp_dict.keys())) updated_product_offer_dict = {} for offer_item in offer_items: replacement_inp = replacement_inp_dict[offer_item.id] new_sku = replacement_inp.get('new_sku') if new_sku and new_sku != offer_item.sku: product_dict = get_product_by_sku(new_sku) if product_dict: product_offer = offer_item.product_offer new_master_product = MasterProduct.query.get( product_dict['master_product_id']) if new_master_product.source_id == product_offer.source_id: best_theme_id = offer_item.best_theme_id db.session.delete(offer_item) offer_item = create_offer_item_from_dict( product_dict, product_offer.id) offer_item.best_theme_id = best_theme_id updated_product_offer_dict[ product_offer.id] = product_offer else: logging.error( 'Cannot replace offer item with id=%s with product by sku=%s - ' 'the source id should be the same (expected=%s, found=%s)', offer_item.id, new_sku, product_offer.source_id, new_master_product.source_id, ) else: logging.error( 'Cannot replace offer item with id=%s - product with sku=%s was not found', offer_item.id, new_sku, ) new_best_theme_id = replacement_inp.get('new_best_theme_id') if new_best_theme_id: offer_item.best_theme_id = from_global_id_assert_type( new_best_theme_id, 'Theme') db.session.flush() for product_offer in updated_product_offer_dict.values(): populate_offer_costs(product_offer)
def mutate_and_get_payload(cls, root, info, identity, theme_selections=()): logging.info('setUserThemeSelections: theme_selections=%s', theme_selections) selection_inp_dict = {} for selection_inp in theme_selections: theme_id = from_global_id_assert_type(selection_inp.theme_id, 'Theme') if theme_id in selection_inp_dict: raise ValueError( 'input.themeSelections.theme_id: duplicate entry for ' + repr(selection_inp.theme_id)) selection_inp_dict[theme_id] = selection_inp user = get_or_create_user(identity.id.subject) themes = ThemeModel.query.filter( ThemeModel.id.in_(selection_inp_dict.keys())).options( joinedload(ThemeModel.theme_group), joinedload('theme_group.user'), ) creators = {} for theme in themes: creators[theme.theme_group.user.id] = theme.theme_group.user selection_inp = selection_inp_dict[theme.id] if selection_inp.selected: user.selected_themes.append(theme) else: try: user.selected_themes.remove(theme) except ValueError: pass db.session.flush() for creator in creators.values(): following_exists = db.session.query( UserModel.query.join(UserModel.selected_themes).join( ThemeModel.theme_group).filter( UserModel.id == user.id, ThemeGroupModel.user_id == creator.id, ).exists()).scalar() if following_exists: user.followed_creators.append(creator) else: user.followed_creators.remove(creator) db.session.flush() for creator in creators.values(): creator.follower_count = db.session.query( user_creators_table).filter( user_creators_table.c.creator_id == creator.id).count() db.session.commit() return SetUserThemeSelections()