Esempio n. 1
0
    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))
Esempio n. 2
0
    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))
Esempio n. 3
0
    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))
Esempio n. 4
0
    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()
Esempio n. 5
0
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)
Esempio n. 6
0
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)
Esempio n. 7
0
    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()))
Esempio n. 8
0
    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)
Esempio n. 9
0
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)
Esempio n. 10
0
    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()