def get_broadcast_audience_of_service_identity_keys_query(service_identity_user, min_age=None, max_age=None,
                                                          gender=None, app_id=None, broadcast_type=None):
    azzert('/' in service_identity_user.email(), 'no slash in %s' % service_identity_user.email())
    qry_string = "SELECT __key__ FROM FriendServiceIdentityConnection " \
                 "WHERE service_identity_email = :service_identity_email"
    qry_params = dict(service_identity_email=service_identity_user.email())
    if min_age is not None:
        if min_age > 130:
            min_age = 130
        # must find users that are born BEFORE today - x years
        # eg. today is 3 jan 2014, min_age is 29; then look for users born before 3 jan 1985 (first day a user can be 29)
        qry_string += " AND birthdate <= :max_birthdate"
        qry_params['max_birthdate'] = get_epoch_from_datetime(datetime.date.today() - relativedelta(years=min_age))
    if max_age is not None:
        if max_age > 130:
            max_age = 130
        # must find users that are born AFTER today + 1 day - (x + 1) years
        # eg. today is 3 jan 2014, max_age is 29; then look for users born after 4 jan 1984 (last day a user can be 29)
        qry_string += " AND birthdate >= :min_birthdate"
        qry_params['min_birthdate'] = get_epoch_from_datetime(
            datetime.date.today() - relativedelta(years=max_age + 1, days=-1))
    if gender is not None and gender != UserProfile.GENDER_MALE_OR_FEMALE:
        qry_string += " AND gender = :gender"
        qry_params['gender'] = gender
    if app_id is not None:
        qry_string += " AND app_id = :app_id"
        qry_params['app_id'] = app_id
    if broadcast_type is not None:
        qry_string += " AND enabled_broadcast_types = :broadcast_type"
        qry_params['broadcast_type'] = broadcast_type
    logging.debug("Broadcast audience query: %s\nparams: %s", qry_string, qry_params)

    qry = db.GqlQuery(qry_string)
    qry.bind(**qry_params)
    return qry
    def test_news_item_target_audience(self):
        today = date.today()
        date_old = today + relativedelta(years=-40)
        date_ancient = today + relativedelta(years=-500)
        date_young = today + relativedelta(years=-10)

        empty_profile = UserProfile(birthdate=None, gender=None)
        profile_old_male = UserProfile(birthdate=get_epoch_from_datetime(date_old),
                                       gender=UserProfile.GENDER_MALE)
        profile_old_female = UserProfile(birthdate=get_epoch_from_datetime(date_old),
                                         gender=UserProfile.GENDER_FEMALE)
        profile_ancient_female = UserProfile(birthdate=get_epoch_from_datetime(date_ancient),
                                             gender=UserProfile.GENDER_FEMALE)
        young_female = UserProfile(birthdate=get_epoch_from_datetime(date_young),
                                   gender=UserProfile.GENDER_FEMALE)

        news_item0 = NewsItem(sticky=False,
                              sender=users.User('*****@*****.**'),
                              app_ids=['rogerthat'],
                              timestamp=now(),
                              rogered=False,
                              target_audience_enabled=False)

        self.assertTrue(news_item0.match_target_audience(profile_old_male))
        self.assertTrue(news_item0.match_target_audience(young_female))
        self.assertTrue(news_item0.match_target_audience(empty_profile))

        news_item1 = NewsItem(sticky=False,
                              sender=users.User('*****@*****.**'),
                              app_ids=['rogerthat'],
                              timestamp=now(),
                              rogered=False,
                              target_audience_enabled=True,
                              target_audience_min_age=0,
                              target_audience_max_age=100,
                              target_audience_gender=UserProfile.GENDER_FEMALE)

        self.assertFalse(news_item1.match_target_audience(empty_profile))
        self.assertFalse(news_item1.match_target_audience(profile_old_male))
        self.assertTrue(news_item1.match_target_audience(profile_old_female))
        self.assertFalse(news_item1.match_target_audience(profile_ancient_female))
        self.assertTrue(news_item1.match_target_audience(young_female))

        news_item2 = NewsItem(sticky=False,
                              sender=users.User('*****@*****.**'),
                              app_ids=['rogerthat'],
                              timestamp=now(),
                              rogered=False,
                              target_audience_enabled=True,
                              target_audience_min_age=18,
                              target_audience_max_age=99,
                              target_audience_gender=UserProfile.GENDER_MALE_OR_FEMALE)

        self.assertFalse(news_item2.match_target_audience(empty_profile))
        self.assertTrue(news_item2.match_target_audience(profile_old_male))
        self.assertTrue(news_item2.match_target_audience(profile_old_female))
        self.assertFalse(news_item2.match_target_audience(profile_ancient_female))
        self.assertFalse(news_item2.match_target_audience(young_female))
Beispiel #3
0
def cancel_charge(customer_id, order_number, charge_id):
    """Cancels a charge so adjustments can be made to the order. Rolls back the next charge date of the subscription order.

    Args:
        customer_id:
        order_number:
        charge_id:

    Returns:
        None
    """
    to_put = list()
    now_ = now()
    charge, order, customer = db.get([Charge.create_key(charge_id, order_number, customer_id),
                                      Order.create_key(customer_id, order_number),
                                      Customer.create_key(customer_id)])
    charge.date_cancelled = now_
    charge.status = Charge.STATUS_CANCELLED
    to_put.append(charge)
    order_items = list(OrderItem.list_by_order(order.key()))
    if order.is_subscription_order:
        months = 0
        for item in order_items:
            product = item.product
            if product.is_subscription and product.price > 0:
                months += item.count
            if not product.is_subscription and product.extra_subscription_months > 0:
                months += product.extra_subscription_months

        if months > 0:
            next_charge_datetime = datetime.datetime.utcfromtimestamp(now()) - relativedelta(months=months)
            order.next_charge_date = get_epoch_from_datetime(next_charge_datetime)
        else:
            order.next_charge_date = Order.default_next_charge_date()
    else:
        extra_months = 0
        for item in order_items:
            product = item.product
            if not product.is_subscription and product.extra_subscription_months > 0:
                extra_months += product.extra_subscription_months

        if extra_months > 0:
            sub_order = Order.get_by_order_number(customer_id, customer.subscription_order_number)
            next_charge_datetime = datetime.datetime.utcfromtimestamp(sub_order.next_charge_date) - relativedelta(
                months=extra_months)
            sub_order.next_charge_date = get_epoch_from_datetime(next_charge_datetime)
            to_put.append(sub_order)
    db.put(to_put)
def _calculate_next_reminder(job_criteria, job_notifications, should_clear=False, skip_today=False):
    if should_clear:
        job_notifications.job_ids = []

    if job_criteria.notifications and \
            job_criteria.notifications.how_often in (JobMatchingCriteriaNotifications.AT_MOST_ONCE_A_DAY,
                                                     JobMatchingCriteriaNotifications.AT_MOST_ONCE_A_WEEK,):
        dt_with_tz_now = datetime.now(tz=pytz.timezone(job_criteria.notifications.timezone))
        if skip_today:
            dt_with_tz_now = dt_with_tz_now + relativedelta(days=1)
        dt_with_tz = dt_with_tz_now.replace(hour=0, minute=0, second=0, microsecond=0)
        dt_with_tz = dt_with_tz + relativedelta(seconds=job_criteria.notifications.delivery_time)
        if dt_with_tz_now >= dt_with_tz:
            dt_with_tz = dt_with_tz + relativedelta(days=1)
        if job_criteria.notifications.how_often in (JobMatchingCriteriaNotifications.AT_MOST_ONCE_A_WEEK,):
            days = ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"]
            weekday = days.index(job_criteria.notifications.delivery_day)
            if weekday != dt_with_tz.weekday() or dt_with_tz_now >= dt_with_tz:
                days_ahead = weekday - dt_with_tz.weekday()
                if days_ahead <= 0:
                    days_ahead += 7
                dt_with_tz = dt_with_tz + relativedelta(days=days_ahead)

        logging.info('reminder date: %s', dt_with_tz)
        dt_without_tz = datetime(dt_with_tz.year, dt_with_tz.month, dt_with_tz.day, dt_with_tz.hour,
                                 dt_with_tz.minute, dt_with_tz.second)
        time_epoch = get_epoch_from_datetime(dt_without_tz)
        time_diff = int((dt_with_tz - pytz.UTC.localize(dt_without_tz)).total_seconds())
        job_notifications.schedule_time = time_epoch + time_diff

    else:
        job_notifications.schedule_time = 0

    job_notifications.put()
def _create_news_for_app_broadcasts(app_broadcast_key):
    app_broadcast = AppBroadcastStatistics.get(app_broadcast_key)
    to_put = []
    for tag, message in zip(app_broadcast.tags, app_broadcast.messages):
        flow_stats = FlowStatistics.get(
            FlowStatistics.create_key(tag,
                                      app_broadcast.service_identity_user))
        if not flow_stats:  # should only happen on dev server
            logging.warn(
                'Not creating news item for app broadcast with tag %s and message %s.',
                tag, message)
            return
        first_property_length = len(flow_stats.step_0_sent)
        timestamp = get_epoch_from_datetime(
            flow_stats.last_entry_datetime_date -
            relativedelta(days=first_property_length))
        news_item = _create_news_item(message, flow_stats.service_identity,
                                      flow_stats.service_user, u'Nieuws')
        flow_stats_to = FlowStatisticsTO.from_model(
            flow_stats, FlowStatisticsTO.VIEW_STEPS, 99999,
            FlowStatisticsTO.GROUP_BY_YEAR)
        news_item.reach = 0
        for step in flow_stats_to.steps:
            for year_stats in step.read_count:
                news_item.reach += year_stats.count

        news_item.timestamp = timestamp + DAY / 2
        news_item.update_timestamp = now()
        to_put.append(news_item)
    if to_put:
        db.put(to_put)
    def get(self):
        offset = int(self.request.GET.get("offset", 0))  # go back <offset> days in the past

        today = datetime.date.today()
        viewed_day = today - relativedelta(months=offset)
        first_day_of_viewed_month = datetime.date(viewed_day.year, viewed_day.month, 1)
        last_day_of_viewed_month = datetime.date(viewed_day.year, viewed_day.month, calendar.monthrange(viewed_day.year, viewed_day.month)[1])

        min_timestamp = get_epoch_from_datetime(first_day_of_viewed_month)
        max_timestamp = get_epoch_from_datetime(last_day_of_viewed_month)

        args = {"activations": get_activation_log(min_timestamp, max_timestamp),
                "current_day":self._epoch_to_str(min_timestamp),
                "next_url":"/mobiadmin/activation_logs?offset=%s" % (offset - 1) if offset else "",
                "back_url":"/mobiadmin/activation_logs?offset=%s" % (offset + 1)}
        path = os.path.join(os.path.dirname(__file__), 'activation_logs.html')
        self.response.out.write(template.render(path, args))
def get_profile_for_facebook_user(access_token, app_user, update=False, language=DEFAULT_LANGUAGE, app_id=App.APP_ID_ROGERTHAT):
    gapi = facebook.GraphAPI(access_token)
    fields = ["id", "first_name", "last_name", "name", "verified", "locale", "gender", "email", "birthday", "link"]
    fb_profile = gapi.get_object("me", fields=','.join(fields))
    logging.debug("/me graph response: %s", fb_profile)

    if not app_user:
        if "email" in fb_profile:
            app_user = create_app_user(users.User(fb_profile["email"]), app_id)
        else:
            raise FailedToBuildFacebookProfileException(
                localize(language, 'There is no e-mail address configured in your facebook account. Please use the e-mail based login.'))

        # TODO we should validate app.user_regex
        # TODO we should check if email is not used for a service account

    couple_facebook_id_with_profile(app_user, access_token)
    profile = get_user_profile(app_user)
    if not profile or update:
        if not profile:
            profile = FacebookUserProfile(parent=parent_key(app_user), key_name=app_user.email())
            profile.app_id = app_id
            avatar = Avatar(user=app_user)
        else:
            avatar = get_avatar_by_id(profile.avatarId)
            if not avatar:
                avatar = Avatar(user=app_user)

        if fb_profile.get("name"):
            profile.name = fb_profile["name"]
        else:
            profile.name = get_human_user_from_app_user(app_user).email().replace("@", " at ")

        if profile.birthdate is None and fb_profile.get("birthday"):
            birthday = fb_profile["birthday"].split("/")
            profile.birthdate = get_epoch_from_datetime(
                datetime.date(int(birthday[2]), int(birthday[0]), int(birthday[1])))

        if profile.gender is None and fb_profile.get("gender"):
            gender = fb_profile["gender"]
            if gender == "male":
                profile.gender = UserProfile.GENDER_MALE
            elif gender == "female":
                profile.gender = UserProfile.GENDER_FEMALE
            else:
                profile.gender = UserProfile.GENDER_CUSTOM

        avatar = _get_and_save_facebook_avatar(app_user, fb_profile["id"], profile, avatar)

        profile.avatarId = avatar.key().id()
        profile.language = language
        profile.profile_url = fb_profile.get("link")
        profile.access_token = access_token
        profile.version = 1
        put_and_invalidate_cache(profile, ProfilePointer.create(app_user))
        update_friends(profile, [u"name", u"avatar"])
        update_mobiles(app_user, profile)
    return profile
Beispiel #8
0
def get_dates_v1(r_timestamp):
    r_timestart = r_timestamp["timestart"]
    start_date = datetime.datetime.strptime(
        "%s %s" % (r_timestamp["date"], r_timestart), "%Y-%m-%d %H:%M:%S")
    start_date = get_epoch_from_datetime(start_date)
    if r_timestamp.get("timeend", None):
        end_date = time.strptime(r_timestamp["timeend"], '%H:%M:%S')
        end_date = long(
            datetime.timedelta(hours=end_date.tm_hour,
                               minutes=end_date.tm_min,
                               seconds=end_date.tm_sec).total_seconds())
    else:
        end_date = 0
    return start_date, end_date
Beispiel #9
0
def get_dates_v2(r_timestamp):
    r_timestart = r_timestamp["timestart"]
    timestamp = long((r_timestamp["date"] + r_timestart) / 1000)
    tz = pytz.timezone('Europe/Brussels')
    dt_with_tz = datetime.datetime.fromtimestamp(timestamp, tz)
    dt_without_tz = datetime.datetime(dt_with_tz.year, dt_with_tz.month,
                                      dt_with_tz.day, dt_with_tz.hour,
                                      dt_with_tz.minute, dt_with_tz.second)
    time_epoch = get_epoch_from_datetime(dt_without_tz)
    time_diff = _get_time_diff_uitdatabank(dt_with_tz, dt_without_tz)
    start_date = time_epoch - time_diff
    if r_timestamp.get("timeend", None):
        end_date = int(r_timestamp["timeend"] / 1000) - time_diff
    else:
        end_date = 0
    return start_date, end_date
def _get_jobs(qry, cursor, language):
    fetch_size = 10
    items, new_cursor, has_more = qry.fetch_page(fetch_size, start_cursor=Cursor.from_websafe_string(cursor) if cursor else None, keys_only=True)

    result = GetJobsResponseTO()
    result.has_criteria = True
    result.items = []
    for m in ndb.get_multi(items):
        job_offer = JobOffer.get_by_id(m.job_id)
        timestamp = get_epoch_from_datetime(m.created)
        interested = m.interested if hasattr(m, 'interested') else False
        job_offer_to = JobOfferTO.fromJobOffer(job_offer, timestamp, interested, language)
        if not job_offer_to:
            continue
        result.items.append(job_offer_to)
    result.cursor = new_cursor.to_websafe_string().decode('utf-8') if new_cursor else None
    result.has_more = has_more
    return result
Beispiel #11
0
def get_expiration_date_from_today(app_id):
    settings = get_city_vouchers_settings(app_id)
    if settings.validity:
        expiration_date = datetime.utcnow().date() + relativedelta(
            months=settings.validity)
        return get_epoch_from_datetime(expiration_date)
Beispiel #12
0
def submit_reservation(year, month, day, hour, minute, name, people, comment, phone, force):
    from solutions.common.bizz.reservation import reserve_table
    service_user = users.get_current_user()
    session_ = users.get_current_session()
    service_identity = session_.service_identity
    return reserve_table(service_user, service_identity, None, get_epoch_from_datetime(datetime(year, month, day, hour, minute)), people, name, phone, comment, force)
Beispiel #13
0
def edit_reservation(reservation_key, people, comment, force=True, new_date=None):
    from solutions.common.bizz.reservation import edit_reservation as edit_reservation_bizz
    new_epoch = 0
    if new_date:
        new_epoch = get_epoch_from_datetime(datetime(new_date.year, new_date.month, new_date.day, new_date.hour, new_date.minute))
    return edit_reservation_bizz(users.get_current_user(), reservation_key, people, comment, force, True if new_date else False, new_epoch)
Beispiel #14
0
def put_google_events(service_user, calendar_str_key, calendar_id, solution,
                      google_calendar_finished, google_events, language):
    to_put = []
    no_title_text = common_translate(language, SOLUTION_COMMON, '(No title)')
    for google_event in google_events:
        try:
            google_event_id = google_event["id"]
            event_parent_key = parent_key(service_user, solution)
            event = Event.all().ancestor(event_parent_key).filter(
                "source =",
                Event.SOURCE_GOOGLE_CALENDAR).filter("external_id =",
                                                     google_event_id).get()
            if not event:
                event = Event(parent=event_parent_key,
                              source=Event.SOURCE_GOOGLE_CALENDAR,
                              external_id=google_event_id)

            if google_event.get("status", "confirmed") == "cancelled":
                if not event.is_saved():
                    continue
                event.deleted = True
            elif not event.deleted:
                event.deleted = False
            event.title = google_event.get('summary', no_title_text)
            event.place = google_event.get("location",
                                           u"").replace(u"\n", u" ")
            event.organizer = google_event.get("organizer",
                                               {}).get("displayName", u"")
            event.description = google_event.get('description', u"")
            event.calendar_id = calendar_id
            event.external_link = google_event["htmlLink"]
            event.start_dates = list()
            event.end_dates = list()

            if google_event["start"].get("dateTime", None):
                start_date_with_tz = dateutil.parser.parse(
                    google_event["start"]["dateTime"])
                end_date_with_tz = dateutil.parser.parse(
                    google_event["end"]["dateTime"])

                day_difference = abs(
                    (end_date_with_tz - start_date_with_tz).days)
                if day_difference == 0:
                    start_epoch = get_epoch_from_datetime(
                        datetime(start_date_with_tz.year,
                                 start_date_with_tz.month,
                                 start_date_with_tz.day,
                                 start_date_with_tz.hour,
                                 start_date_with_tz.minute))
                    event.start_dates.append(start_epoch)
                    end_epoch = get_epoch_from_datetime(
                        datetime(end_date_with_tz.year, end_date_with_tz.month,
                                 end_date_with_tz.day, end_date_with_tz.hour,
                                 end_date_with_tz.minute))
                    end_date = datetime.fromtimestamp(end_epoch)
                    event.end_dates.append(
                        int(
                            timedelta(
                                hours=end_date.hour,
                                minutes=end_date.minute,
                                seconds=end_date.second).total_seconds()))


# TODO: multi day event
#                 else:
#                     start_date = datetime.strptime(google_event["start"]["date"], '%Y-%m-%d')
#                     end_date = datetime.strptime(google_event["end"]["date"], '%Y-%m-%d')
#                     day_difference = abs((end_date - start_date).days)

            if event.start_dates:
                event.first_start_date = event.start_dates[0]
                event.last_start_date = event.start_dates[-1]
                to_put.append(event)
            else:
                logging.info("Skipping event because it had no start_dates")
                logging.debug(google_event)
        except:
            logging.warn('Failed to put Google Event: %s', google_event)
            raise

    if to_put:
        db.put(to_put)

    if google_calendar_finished:

        def trans():
            scgs = SolutionCalendarGoogleSync.get_by_key_name(
                service_user.email())
            if not scgs:
                return True  # update was run from saving a calendar
            if calendar_str_key in scgs.google_calendar_keys:
                scgs.google_calendar_keys.remove(calendar_str_key)
                if not scgs.google_calendar_keys:
                    scgs.delete()
                    return True
                scgs.put()
                return False

        if db.run_in_transaction(trans):
            from solutions.common.bizz.provisioning import populate_identity_and_publish
            sln_settings = get_solution_settings(service_user)
            sln_main_branding = get_solution_main_branding(service_user)
            deferred.defer(populate_identity_and_publish, sln_settings,
                           sln_main_branding.branding_key)
Beispiel #15
0
def new_event_received(service_user, message_flow_run_id, member, steps,
                       end_id, end_message_flow_id, parent_message_key, tag,
                       result_key, flush_id, flush_message_flow_id,
                       service_identity, user_details):
    from solutions.common.bizz.messaging import _get_step_with_id

    logging.info("_flow_member_result_new_event: \n %s" % steps)

    calendar = _get_step_with_id(steps, 'message_calendar')

    title = _get_step_with_id(steps, 'message_title')
    if not title:
        logging.error(
            "Did not find step with id 'title'. Can not process message_flow_member_result with tag %s"
            % tag)
        return None

    date_ = _get_step_with_id(steps, 'message_date')
    if not date_:
        logging.error(
            "Did not find step with id 'date'. Can not process message_flow_member_result with tag %s"
            % tag)
        return None

    start_time = _get_step_with_id(steps, 'message_start_time')
    if not start_time:
        logging.error(
            "Did not find step with id 'start_time'. Can not process message_flow_member_result with tag %s"
            % tag)
        return None

    end_time = _get_step_with_id(steps, 'message_end_time')
    if not end_time:
        logging.error(
            "Did not find step with id 'end_time'. Can not process message_flow_member_result with tag %s"
            % tag)
        return None

    description = _get_step_with_id(steps, 'message_description')
    if not description:
        logging.error(
            "Did not find step with id 'description'. Can not process message_flow_member_result with tag %s"
            % tag)
        return None

    place = _get_step_with_id(steps, 'message_place')
    if not place:
        logging.error(
            "Did not find step with id 'place'. Can not process message_flow_member_result with tag %s"
            % tag)
        return None

    photo = _get_step_with_id(steps, 'message_photo')
    if not photo:
        logging.error(
            "Did not find step with id 'photo'. Can not process message_flow_member_result with tag %s"
            % tag)
        return None

    sln_settings = get_solution_settings(service_user)
    app_user = user_details[0].toAppUser()
    calendars_ids_admin = get_solution_calendar_ids_for_user(
        service_user, sln_settings.solution, app_user)

    if len(calendars_ids_admin) == 0:
        logging.warn("User %s isn't a calendar admin anymore" %
                     app_user.email())
        return None

    calendar_id = None
    if calendar and calendar.form_result.result:
        calendar_id = long(calendar.form_result.result.value)
    else:
        if sln_settings.default_calendar in calendars_ids_admin:
            calendar_id = sln_settings.default_calendar
        else:
            calendar_id = calendars_ids_admin[0]

    sc = SolutionCalendar.get_by_id(
        calendar_id, parent_key(service_user, sln_settings.solution))
    if not sc:
        logging.warn("Calendar %s does not exists anymore" % calendar_id)
        return None

    event = Event(parent=parent_key(service_user, sln_settings.solution))
    event.picture_version = 0
    event.title = title.form_result.result.value
    event.place = place.form_result.result.value
    event.description = description.form_result.result.value

    start_date = get_epoch_from_datetime(
        datetime.fromtimestamp(date_.form_result.result.value).date()
    ) + start_time.form_result.result.value
    event.last_start_date = start_date
    event.start_dates = [start_date]
    event.end_dates = [end_time.form_result.result.value]
    event.first_start_date = event.get_first_event_date()
    event.calendar_id = calendar_id
    if photo.form_result:
        result = urlfetch.fetch(photo.form_result.result.value, {},
                                "GET", {},
                                False,
                                False,
                                deadline=10 * 60)
        if result.status_code != 200:
            logging.error(
                "Failed to download photo upload for new event whith link: %s"
                % photo.form_result.result)
            picture = None
        else:
            img_str = result.content
            img_b64 = base64.b64encode(img_str)

            previous_len_img = len(img_b64)
            while len(img_b64) > 512 * 1024:
                img = images.Image(img_str)
                img.im_feeling_lucky()
                img_str = img.execute_transforms(
                    output_encoding=images.JPEG)  # Reduces quality to 85%
                img_b64 = base64.b64encode(img_str)

                if previous_len_img <= len(img_b64):
                    break
                previous_len_img = len(img_b64)

            picture = "data:image/jpg;base64,%s" % img_b64
    else:
        picture = None
    event.picture = picture
    event.put()

    send_message(service_user, u"solutions.common.calendar.update")
    deferred.defer(common_provision, service_user)
    return None
    def trans():
        charge = None
        expired_subscription, customer = db.get([ExpiredSubscription.create_key(customer_id),
                                                       Customer.create_key(customer_id)])
        expired_subscription.status = status
        expired_subscription.status_updated_timestamp = now()

        if status == ExpiredSubscription.STATUS_WILL_LINK_CREDIT_CARD:
            # Create a task for regiomanager to check if the customer has linked his credit card after two weeks.
            # the ExpiredSubscription object from this customer will be cleaned up in recurrentbilling the day after he has linked it.
            to_put.append(expired_subscription)
            team, prospect = db.get([RegioManagerTeam.create_key(customer.team_id),
                                     Prospect.create_key(customer.prospect_id)])
            execution_time = now() + DAY * 14
            date_string = datetime.datetime.utcfromtimestamp(execution_time).strftime(u'%A %d %b %Y')
            comment = u'Check if the customer has linked his creditcard (for automatic subscription renewal).' \
                      u' If he hasn\'t linked it before %s, contact him again.' % date_string
            task = create_task(current_user.email(), prospect, team.support_manager, execution_time,
                               ShopTask.TYPE_CHECK_CREDIT_CARD, prospect.app_id, comment=comment)
            to_put.append(task)

        elif status == ExpiredSubscription.STATUS_EXTEND_SUBSCRIPTION:
            # Creates a new charge using the customer his subscription order.
            subscription_order, team = db.get([Order.create_key(customer.id, customer.subscription_order_number),
                                               RegioManagerTeam.create_key(customer.team_id)])
            extension_order_item_keys = list()
            order_items = list(OrderItem.list_by_order(subscription_order.key()))
            products_to_get = list()
            for item in order_items:
                products_to_get.append(Product.create_key(item.product_code))
            products = {p.code: p for p in Product.get(products_to_get)}
            # extend per year
            months = 12
            total_amount = 0
            for item in order_items:
                product = products[item.product_code]
                if product.is_subscription and item.price > 0:
                    total_amount += months * item.price
                elif not product.is_subscription and (product.is_subscription_discount or product.extra_subscription_months > 0):
                    total_amount += months * item.price
                elif product.is_subscription_extension:
                    total_amount += months * item.price
                    extension_order_item_keys.append(item.key())

            if total_amount <= 0:
                raise BusinessException('The created charge has a negative amount (%d)' % total_amount)
            next_charge_datetime = datetime.datetime.utcfromtimestamp(now()) + relativedelta(months=months)
            subscription_order.next_charge_date = get_epoch_from_datetime(next_charge_datetime)
            to_put.append(subscription_order)

            # reconnect all previously connected friends if the service was disabled in the past
            if customer.service_disabled_at != 0:
                deferred.defer(set_service_enabled, customer.id, _transactional=True)

            vat_pct = get_vat_pct(customer, team)
            charge = Charge(parent=subscription_order)
            charge.date = now()
            charge.type = Charge.TYPE_SUBSCRIPTION_EXTENSION
            charge.subscription_extension_length = months
            charge.subscription_extension_order_item_keys = extension_order_item_keys
            charge.amount = total_amount
            charge.vat_pct = vat_pct
            charge.vat = int(total_amount * vat_pct / 100)
            charge.total_amount = charge.amount + charge.vat
            charge.currency_code = team.legal_entity.currency_code
            to_put.append(charge)
            to_delete.append(expired_subscription)

        db.put(to_put)
        if to_delete:
            db.delete(to_delete)

        return charge
Beispiel #17
0
    def test_create_restaurant_identity(self):
        self.set_datastore_hr_probability(1)

        root_proj = os.path.join(os.path.dirname(__file__), '..', '..', '..', '..', '..')
        branding_url = os.path.join(root_proj, 'rogerthat-backend', 'src-test', 'rogerthat_tests', 'mobicage', 'bizz', 'nuntiuz.zip')

        email = u"*****@*****.**"
        name = u"resto_soluton"
        service_user = users.User(email)

        create_service(email=email, name=name, password=u"test1", languages=[u"en"], solution=SOLUTION_FLEX,
                       category_id=None, organization_type=ServiceProfile.ORGANIZATION_TYPE_PROFIT,
                       fail_if_exists=False)

        solutionSettings = SolutionSettings(key=SolutionSettings.create_key(service_user), name=name,
                            menu_item_color=None, address=u"lochristi", phone_number=None,
                            currency=u"€", main_language=DEFAULT_LANGUAGE, solution=SOLUTION_FLEX)

        solutionSettings.holidays = []
        solutionSettings.holiday_out_of_office_message = u'holiday-out-of-office'

        settings = RestaurantSettings(key=RestaurantSettings.create_key(service_user))
        settings.language = DEFAULT_LANGUAGE

        stream = StringIO()
        stream.write(open(branding_url).read())
        stream.seek(0)

        main_branding = SolutionMainBranding(key=SolutionMainBranding.create_key(service_user))
        main_branding.blob = db.Blob(stream.read())
        main_branding.branding_key = None

        settings.shifts = Shifts()

        shift = Shift()
        shift.name = u'shift-lunch'
        shift.capacity = 50
        shift.max_group_size = 6
        shift.leap_time = 30
        shift.threshold = 70
        shift.start = 12 * 60 * 60
        shift.end = 14 * 60 * 60
        shift.days = [1, 2, 3, 4, 5, 6, 7]
        shift.comment = u'shift-comment0'
        settings.shifts.add(shift)

        shift = Shift()
        shift.name = u'shift-dinner'
        shift.capacity = 50
        shift.max_group_size = 6
        shift.leap_time = 30
        shift.threshold = 70
        shift.start = 18 * 60 * 60
        shift.end = 21 * 60 * 60
        shift.days = [1, 2, 3, 4, 5, 6, 7]
        shift.comment = u'shift-comment1'
        settings.shifts.add(shift)

        put_and_invalidate_cache(solutionSettings, settings, main_branding)

        date_ = datetime.datetime.combine(datetime.date.today() + datetime.timedelta(days=10), datetime.datetime.min.time())
        date_ = date_ + datetime.timedelta(hours=19)
        today_ = get_epoch_from_datetime(date_)
        service_identity = None

        user_detail = UserDetailsTO.fromUserProfile(get_user_profile(users.get_current_user()))

        reservationOkKey, reservationOk = \
            self._test_reserve_table(service_user, service_identity, user_details=[user_detail], date=today_, people=3,
                                     name=u"text Name", phone=None, comment=u"comment", force=False)
        reservationTooMany = self._test_reserve_table(service_user, service_identity, user_details=[user_detail],
                                                      date=today_, people=50, name=u"text Name", phone=None,
                                                      comment=u"comment", force=False)

        self.assertEqual(STATUS_AVAILABLE, reservationOk)
        self.assertEqual(STATUS_TOO_MANY_PEOPLE, reservationTooMany)

        editReservationOk = edit_reservation(service_user, reservationOkKey, people=4, comment=None, force=False)
        self.assertEqual(STATUS_AVAILABLE, editReservationOk)

        cancel_reservation(service_user, reservationOkKey, notified=False)
        move_reservation(service_user, None, reservationOkKey, u'shift-lunch')
Beispiel #18
0
def export_invoices(year, month):
    start_date = datetime.date(year, month, 1)
    end_date = start_date + relativedelta(months=1)

    qry = Invoice.all() \
        .filter('date >=', get_epoch_from_datetime(start_date)) \
        .filter('date <', get_epoch_from_datetime(end_date))

    invoices = list()
    order_keys = set()
    all_products = dict(((p.code, p) for p in Product.all()))
    for invoice_model in qry:
        i = model_to_dict(invoice_model)
        order_key = invoice_model.parent_key().parent()
        i['invoice_number'] = invoice_model.invoice_number
        i['order_items'] = map(model_to_dict,
                               OrderItem.all().ancestor(order_key))
        if invoice_model.charge.is_recurrent:
            # only apply recurrent charges
            for order_item in reversed(i['order_items']):
                order_item[
                    'count'] = invoice_model.charge.subscription_extension_length or 1
                product = all_products[order_item['product_code']]
                if not (product.is_subscription_discount
                        or product.is_subscription
                        or product.is_subscription_extension):
                    i['order_items'].remove(order_item)

            # add the subscription extensions like XCTY
            if invoice_model.charge.subscription_extension_order_item_keys:
                known_extension_item_keys = [
                    item['_key'] for item in i['order_items']
                ]

                extension_order_items = db.get(
                    invoice_model.charge.subscription_extension_order_item_keys
                )
                for item in extension_order_items:
                    item.count = 1
                    if str(item.key()) not in known_extension_item_keys:
                        i['order_items'].append(model_to_dict(item))

        i['order_key'] = order_key
        i['currency'] = invoice_model.currency_code
        order_keys.add(order_key)
        invoices.append(i)

    orders = {o.key(): o for o in db.get(order_keys)}

    contact_keys = set()
    customer_keys = set()
    for i in invoices:
        order_model = orders[i['order_key']]
        del i['order_key']
        i['customer_key'] = order_model.customer_key
        i['contact_key'] = order_model.contact_key
        i['manager'] = None if not order_model.manager else order_model.manager.email(
        )
        customer_keys.add(order_model.customer_key)
        contact_keys.add(order_model.contact_key)

    del orders

    customer_and_contact_models = {
        m.key(): m
        for m in db.get(customer_keys.union(contact_keys))
    }

    # filter invoices for customers of resellers
    reseller_ids = [
        k.id() for k in LegalEntity.list_non_mobicage(keys_only=True)
    ]
    reseller_team_ids = [
        t.id for t in RegioManagerTeam.all().filter('legal_entity_id IN',
                                                    reseller_ids)
    ]

    for i in reversed(invoices):
        customer_model = customer_and_contact_models[i['customer_key']]
        if customer_model.team_id in reseller_team_ids:
            invoices.remove(i)
            continue
        del i['customer_key']
        i['customer'] = model_to_dict(customer_model)
        contact_model = customer_and_contact_models[i['contact_key']]
        del i['contact_key']
        i['contact'] = model_to_dict(contact_model)

    del customer_and_contact_models

    return sorted(invoices,
                  key=lambda i: int(i['invoice_number'].split('.')[-1]))