コード例 #1
0
def _retailer_message(store_id,
                      subject,
                      body,
                      date_offer_expiration,
                      message_type,
                      offer_title,
                      gift_title,
                      gift_description,
                      sender_name="Test Store",
                      receiver_count=100,
                      is_read=False,
                      filter="all"):
    # first create the message
    message = Message(store_id=store_id, subject=subject, body=body,
        filter=filter, sender_name=sender_name, offer_title=offer_title,
        message_type=message_type, date_offer_expiration=\
        date_offer_expiration, is_read=is_read, gift_description=\
        gift_description, gift_title=gift_title)
    message.create()

    return cloud_call(
        "retailer_message", {
            "subject": subject,
            "message_id": message.objectId,
            "store_id": store_id,
            "store_name": sender_name,
            "filter": filter,
        })
コード例 #2
0
def request_redeem_offers(patron_store_id):
    """
    Requests all offers in the given patron_store's MessageStatus
    """
    ps = PatronStore.objects().get(objectId=patron_store_id,
                                   include="Patron,Store")
    patron, store = ps.patron, ps.store
    message_statuses = patron.get("receivedMessages",
                                  redeem_available="yes",
                                  limit=999)

    for ms in message_statuses:
        message = Message.objects().get(objectId=ms.Message)
        cloud_call(
            "request_redeem", {
                "patron_id": ps.Patron,
                "store_id": ps.Store,
                "store_location_id": store.store_locations[0].objectId,
                "patron_store_id": ps.objectId,
                "title": message.offer_title,
                "reward_id": None,
                "num_punches": 0,
                "name": patron.get_fullname(),
                "message_status_id": ms.objectId,
            })
コード例 #3
0
ファイル: test.py プロジェクト: mjhshin/repunch_web
def _retailer_message(store_id, subject, body, 
    date_offer_expiration, message_type, offer_title, gift_title,
    gift_description, sender_name="Test Store", receiver_count=100,
    is_read=False, filter="all"):
    # first create the message
    message = Message(store_id=store_id, subject=subject, body=body,
        filter=filter, sender_name=sender_name, offer_title=offer_title,
        message_type=message_type, date_offer_expiration=\
        date_offer_expiration, is_read=is_read, gift_description=\
        gift_description, gift_title=gift_title)
    message.create()
    
    return cloud_call("retailer_message", {
        "subject": subject,
        "message_id": message.objectId,
        "store_id": store_id,
        "store_name": sender_name,
        "filter": filter,
        
    })
コード例 #4
0
ファイル: views.py プロジェクト: mjhshin/repunch_web
def feedback_delete(request, feedback_id):
    """
    Handles requests to delete the feedback with the given feedback_id.
    """
    store = SESSION.get_store(request.session)

    # get the feedback from the messages_received_list in session cache
    messages_received_list = SESSION.get_messages_received_list(\
        request.session)
    i_remove, feedback = 0, None
    for ind, m in enumerate(messages_received_list):
        if m.objectId == feedback_id:
            feedback = m
            i_remove = ind
            break

    if not feedback:
        # feedback not found - it may have been deleted
        return redirect(reverse('messages_index')+ "?%s" %\
             urllib.urlencode({'error': 'Feedback not found.'}))

    # we don't actually delete the feedback object,
    # we just remove from the store's relation
    store.remove_relation("ReceivedMessages_", [feedback.objectId])

    # remove it from the messages_received_list in session cache
    messages_received_list.pop(i_remove)
    request.session['messages_received_list'] =\
        messages_received_list

    # notify other dashboards logged into the same store of this change
    comet_receive(
        store.objectId, {
            COMET_RECEIVE_KEY_NAME: COMET_RECEIVE_KEY,
            "deletedFeedback": Message(objectId=feedback.objectId).jsonify(),
        })

    return redirect(reverse('messages_index')+ "?%s" %\
        urllib.urlencode({'success':'Feedback has been deleted.',
            'tab_feedback':1}))
コード例 #5
0
 def create_offer(self):
     offer = Message.objects().create(**{
         'subject': u'test_request_validate_redeem script message offer',
         'body': u'test_request_validate_redeem script generate offer', 
         'sender_name': u'test_request_validate_redeem', 
         'store_id': self.store.objectId, 
         'is_read': False, 
         'offer_redeemed': False, 
         'date_offer_expiration': timezone.now()+relativedelta(days=1), 
         'filter': u'all', 
         'offer_title': u'test_request_validate_redeem script offer', 
         'message_type': 'offer', 
     })
     
     cloud_call("retailer_message", {
         "filter": offer.filter,
         "store_name": self.store.store_name,
         "message_id": offer.objectId,
         "store_id": self.store.objectId,
         "subject": offer.subject,
     })
     
     return offer
コード例 #6
0
ファイル: test.py プロジェクト: mjhshin/repunch_web
def request_redeem_offers(patron_store_id):
    """
    Requests all offers in the given patron_store's MessageStatus
    """
    ps = PatronStore.objects().get(objectId=patron_store_id,
        include="Patron,Store")
    patron, store = ps.patron, ps.store
    message_statuses = patron.get("receivedMessages",
        redeem_available="yes", limit=999)

    for ms in message_statuses:
        message = Message.objects().get(objectId=ms.Message)
        cloud_call("request_redeem", {
            "patron_id": ps.Patron,
            "store_id": ps.Store,
            "store_location_id": store.store_locations[0].objectId,
            "patron_store_id": ps.objectId,
            "title": message.offer_title,
            "reward_id": None,
            "num_punches": 0,
            "name": patron.get_fullname(),
            "message_status_id": ms.objectId,
        })
コード例 #7
0
ファイル: __init__.py プロジェクト: mjhshin/repunch_web
    def processCometReceivedDict(session, postDict):
        employees_pending_list =\
            SESSION.get_employees_pending_list(session)
        employees_approved_list =\
            SESSION.get_employees_approved_list(session)
        messages_received_list =\
            SESSION.get_messages_received_list(session)
        redemptions_pending =\
            SESSION.get_redemptions_pending(session)
        redemptions_past =\
            SESSION.get_redemptions_past(session)

        #############################################################
        # FEEDBACKS_UNREAD ##################################
        newFeedback = postDict.get('newFeedback')
        if newFeedback:
            messages_received_ids =\
                [ fb.objectId for fb in messages_received_list ]
            m = Message(**newFeedback)
            if m.objectId not in messages_received_ids:
                messages_received_list.insert(0, m)

            session['messages_received_list'] =\
                messages_received_list

        #############################################################
        # FEEDBACK DELETED ##################################
        deletedFeedback = postDict.get("deletedFeedback")
        if deletedFeedback:
            fb = Message(**deletedFeedback)
            for i, mro in enumerate(messages_received_list):
                if fb.objectId == mro.objectId:
                    messages_received_list.pop(i)
                    break
            session['messages_received_list'] =\
                messages_received_list

        #############################################################
        # MESSAGE SENT ##################################
        # need to check if this new message is an original message
        # or a reply to a feedback (the message sent by the patron)!
        # also may increment the message count!
        newMessage = postDict.get("newMessage")
        if newMessage:
            messages_received_ids =\
                    [ fb.objectId for fb in messages_received_list ]
            messages_sent_list =\
                SESSION.get_messages_sent_list(session)
            messages_sent_ids =\
                [ msg.objectId for msg in messages_sent_list ]
            m = Message(**newMessage)
            if m.objectId not in messages_sent_ids and\
                m.message_type != FEEDBACK:
                messages_sent_list.insert(0, m)
                if 'message_count' in session:
                    session['message_count'] =\
                        int(session['message_count']) + 1
            # update an existing feedback
            if m.objectId in messages_received_ids and\
                m.message_type == FEEDBACK:
                for i, mrl in enumerate(messages_received_list):
                    if mrl.objectId == m.objectId:
                        messages_received_list.pop(i)
                        messages_received_list.insert(i, m)
                        break
            session['messages_received_list'] =\
                messages_received_list
            session['messages_sent_list'] = messages_sent_list

        #############################################################
        # EMPLOYEES_PENDING ##################################
        # must also check if employee is already approved!
        pendingEmployee = postDict.get("pendingEmployee")
        if pendingEmployee:
            employees_approved_ids =\
                [ emp.objectId for emp in employees_approved_list ]
            employees_pending_ids =\
                [ emp.objectId for emp in employees_pending_list ]
            e = Employee(**pendingEmployee)
            if e.objectId not in employees_pending_ids and\
                e.objectId not in employees_approved_ids:
                employees_pending_list.insert(0, e)

            session['employees_pending_list'] =\
                employees_pending_list

        #############################################################
        # EMPLOYEES APPROVED (pending to approved) #################
        approvedEmployee = postDict.get("approvedEmployee")
        if approvedEmployee:
            emp = Employee(**approvedEmployee)
            # first check if the employee is in the pending list
            # if not then check if it is already approved
            for i, emp_pending in\
                enumerate(employees_pending_list):
                if emp.objectId == emp_pending.objectId:
                    emp = employees_pending_list.pop(i)
                    emp.status = APPROVED
                    employees_approved_list.insert(0, emp)
                    break

            session['employees_pending_list'] =\
                employees_pending_list
            session['employees_approved_list'] =\
                employees_approved_list

        #############################################################
        # EMPLOYEES NEW (straight to approved) #################
        newEmployee = postDict.get("newEmployee")
        if newEmployee:
            employees_approved_ids =\
                [ emp.objectId for emp in employees_approved_list ]
            emp = Employee(**newEmployee)
            if emp.objectId not in employees_approved_ids:
                employees_approved_list.insert(0, emp)
                session['employees_approved_list'] =\
                    employees_approved_list

        #############################################################
        # EMPLOYEES DELETED/DENIED/REJECTED (pending/approved to pop)!
        deletedEmployee = postDict.get("deletedEmployee")
        if deletedEmployee:
            emp = Employee(**deletedEmployee)
            # check in approved emps
            for i, cop in enumerate(employees_approved_list):
                if cop.objectId == emp.objectId:
                    employees_approved_list.pop(i)
                    break

            # check in pending emps
            for i, cop in enumerate(employees_pending_list):
                if cop.objectId == emp.objectId:
                    employees_pending_list.pop(i)
                    break

            session['employees_approved_list'] =\
                employees_approved_list
            session['employees_pending_list'] =\
                employees_pending_list

        #############################################################
        # EMPLOYEE UPDATED PUNCHES
        updatedEmployeePunch = postDict.get("updatedEmployeePunch")
        if updatedEmployeePunch:
            u_emp = Employee(**updatedEmployeePunch)
            for emp in employees_approved_list:
                if u_emp.objectId == emp.objectId:
                    emp.set("lifetime_punches", u_emp.lifetime_punches)
                    break
            session['employees_approved_list'] =\
                employees_approved_list

        #############################################################
        # REDEMPTIONS PENDING
        ### Only added to cache if it has the store_location_id as
        ### active_store_location_id
        pendingRedemption = postDict.get("pendingRedemption")
        if pendingRedemption:
            rr = RedeemReward(**pendingRedemption)

            # store_location_id can be null for backwards compat
            if not rr.store_location_id or rr.store_location_id ==\
                session.get('active_store_location_id'):
                redemptions_pending_ids =\
                    [ red.objectId for red in redemptions_pending ]
                redemptions_past_ids =\
                    [ red.objectId for red in redemptions_past ]
                # need to check here if the redemption is new because
                # the dashboard that validated it will also receive
                # the validated redemption back.
                if rr.objectId not in redemptions_past_ids and\
                    rr.objectId not in redemptions_pending_ids:
                    redemptions_pending.insert(0, rr)

                session['redemptions_pending'] =\
                    redemptions_pending

        #############################################################
        # REDEMPTIONS APPROVED (pending to history)
        # Save cpu by skipping those that do not have the same
        # store_location_id as active_store_location_id
        approvedRedemption = postDict.get("approvedRedemption")
        if approvedRedemption:
            redemp = RedeemReward(**approvedRedemption)

            # store_location_id can be null for backwards compat
            if not redemp.store_location_id or redemp.store_location_id ==\
                session.get('active_store_location_id'):
                # check if redemp is still in pending
                for i, redem in enumerate(redemptions_pending):
                    if redem.objectId == redemp.objectId:
                        r = redemptions_pending.pop(i)
                        r.is_redeemed = True
                        r.updatedAt = redemp.updatedAt
                        redemptions_past.insert(0, r)
                        break
                # if not then check if it is in the history already
                # the above shouldn't happen!

                session['redemptions_pending'] =\
                    redemptions_pending
                session['redemptions_past'] =\
                    redemptions_past

        #############################################################
        # REDEMPTIONS DELETED ##############################
        # remove from pending (should not be in history!)
        # Save cpu by skipping those that do not have the same
        # store_location_id as active_store_location_id
        deletedRedemption = postDict.get("deletedRedemption")
        if deletedRedemption:
            redemp = RedeemReward(**deletedRedemption)

            # store_location_id can be null for backwards compat
            if not redemp.store_location_id or redemp.store_location_id ==\
                session.get('active_store_location_id'):
                # check if redemp is still in pending
                for i, redem in enumerate(redemptions_pending):
                    if redem.objectId == redemp.objectId:
                        redemptions_pending.pop(i)
                        break

                session['redemptions_pending'] =\
                    redemptions_pending

        #############################################################
        # STORE UPDATED ##############################
        updatedStore = postDict.get("updatedStore")
        if updatedStore:
            store = Store(**updatedStore)
            # have to add the image url manually
            store.thumbnail_image_url = updatedStore.get("thumbnail_image_url")
            store.cover_image_url = updatedStore.get("cover_image_url")
            # below here for backwards compat
            store.store_avatar_url = store.thumbnail_image_url
            session['store'] = store

        updatedStoreThumbnailName = postDict.get("updatedStoreThumbnailName")
        if updatedStoreThumbnailName:
            store = session['store']
            store.thumbnail_image = updatedStoreThumbnailName
            store.thumbnail_image_url = postDict.get(
                "updatedStoreThumbnailUrl")
            # below here for backwards compat
            store.store_avatar = store.thumbnail_image
            store.store_avatar_url = store.thumbnail_image_url
            session['store'] = store

        updatedStoreCoverName = postDict.get("updatedStoreCoverName")
        if updatedStoreCoverName:
            store = session['store']
            store.cover_image = updatedStoreCoverName
            store.cover_image_url = postDict.get("updatedStoreCoverUrl")
            session['store'] = store

        # this is in the settings tab in the dashboard but the field
        # is in the Store class
        updatedPunchesFacebook_int =\
            postDict.get("updatedPunchesFacebook_int")
        if updatedPunchesFacebook_int:
            store = session['store']
            store.punches_facebook = int(updatedPunchesFacebook_int)
            session['store'] = store

        #############################################################
        # STORE LOCATION UPDATED ##############################
        ### Note that this is also being used to insert new StoreLocations
        updatedStoreLocation = postDict.get("updatedStoreLocation")
        if updatedStoreLocation:
            store_location = StoreLocation(**updatedStoreLocation)
            session['store_locations'][store_location.objectId] =\
                store_location

            try:  # also update the store_timezone
                session['store_timezone'] =\
                    pytz.timezone(store_location.get('store_timezone'))
            except Exception:  # assign a default timezone
                session['store_timezone'] =\
                    pytz.timezone(TIME_ZONE)

        #############################################################
        # ACCOUNT UPDATED ##############################
        updatedAccount = postDict.get("updatedAccount")
        if updatedAccount:
            updatedAccountObject = Account(**updatedAccount)
            # need to make sure that these are the same accounts!
            if session['account'].objectId ==\
                updatedAccountObject.objectId:
                session['account'] = updatedAccountObject

        #############################################################
        # SUBSCRIPTION UPDATED ##############################
        updatedSubscription =\
            postDict.get("updatedSubscription")
        if updatedSubscription:
            subscription = Subscription(**updatedSubscription)
            store = session["store"]
            store.set('subscription', subscription)
            store.set('Subscription', subscription.objectId)
            session['subscription'] = subscription
            session['store'] = store

        #############################################################
        # SETTINGS UPDATED ##############################
        updatedSettings = postDict.get("updatedSettings")
        if updatedSettings:
            settings = Settings(**updatedSettings)
            store = session["store"]
            store.set('settings', settings)
            store.set("Settings", settings.objectId)
            session['settings'] = settings
            session['store'] = store

        #############################################################
        # REWARDS NEW ##############################
        newReward = postDict.get("newReward")
        if newReward:
            store = session['store']
            rewards = store.get("rewards")
            rewards_ids = [r['reward_id'] for r in rewards]
            if newReward['reward_id'] not in rewards_ids:
                rewards.append(newReward)
            store.rewards = rewards
            session['store'] = store

        #############################################################
        # REWARDS UPDATED ##############################
        updatedReward = postDict.get('updatedReward')
        if updatedReward:
            store = session['store']
            mod_rewards = store.get("rewards")
            for i, mreward in enumerate(mod_rewards):
                # [{"reward_name":"Free bottle of wine",
                # "description":"Must be under $25 in value",
                # "punches":10,"redemption_count":0,reward_id:0},]
                if updatedReward['reward_id'] == mreward['reward_id']:
                    if updatedReward.has_key("redemption_count"):
                        mod_rewards[i]['redemption_count'] =\
                            updatedReward['redemption_count']
                    if updatedReward.has_key("reward_name"):
                        mod_rewards[i]['reward_name'] =\
                            updatedReward['reward_name']
                    if updatedReward.has_key("punches"):
                        mod_rewards[i]['punches'] =\
                            updatedReward['punches']
                    if updatedReward.has_key("description"):
                        mod_rewards[i]['description'] =\
                            updatedReward['description']
                    break

            store.rewards = mod_rewards
            session['store'] = store

        #############################################################
        # REWARDS DELETED ##############################
        deletedReward = postDict.get("deletedReward")
        if deletedReward:
            store = session['store']
            rewards = store.get("rewards")
            rewards_ids = [r['reward_id'] for r in rewards]
            if deletedReward['reward_id'] in rewards_ids:
                for i, r in enumerate(rewards):
                    if r['reward_id'] == deletedReward['reward_id']:
                        rewards.pop(i)
                        break
            store.rewards = rewards
            session['store'] = store

        #############################################################
        # PATRONSTORE_COUNT ##################################
        patronStore_int = postDict.get('patronStore_int')
        if patronStore_int:
            patronStore_int = int(patronStore_int)
            session['patronStore_count'] = patronStore_int
コード例 #8
0
ファイル: views.py プロジェクト: mjhshin/repunch_web
def feedback_reply(request, feedback_id):
    """
    Render the feedback reply template.
    """
    account = request.session['account']
    store = SESSION.get_store(request.session)
    # data to be passed in the templace context
    data = {
        'messages_nav': True,
        'from_address': store.get("store_name"),
    }

    # get from the messages_received_list in session cache
    messages_received_list = SESSION.get_messages_received_list(\
        request.session)
    i_remove, feedback = 0, None
    for ind, m in enumerate(messages_received_list):
        if m.objectId == feedback_id:
            feedback = m
            i_remove = ind
            break

    if not feedback:
        # feedack not found - redirect to messages page with error message
        return redirect(reverse('messages_index')+ "?%s" %\
             urllib.urlencode({'error': 'Feedback not found.'}))

    if request.method == 'POST':
        # user submitted reply form
        body = request.POST.get('body')
        if body is not None:
            # strip the body so that it doesn't have trailing or
            # leading whitespaces
            body = body.strip()
        else:
            body = ""

        data['body'] = body

        if len(body) == 0:
            # body cannot be empty
            data['error'] = 'Please enter a message.'

        elif len(body) > 750:
            # body cannot exceed 750 cahracters
            data['error'] = 'Body must be less than 750 characters.'

        elif feedback.get('Reply'):
            # double check if feedback already has a reply
            # should not go here unless it is a hacker
            return redirect(reverse('messages_index')+ "?%s" %\
                 urllib.urlencode({'error':\
                    'Feedback has already been replied to.'}))

        else:
            # all valid - this method of validation is dirty and not
            # the way to do it in Django. Use a form instead.
            # I just got lazy here.

            # create the Parse Message object
            msg = Message.objects().create(message_type=\
                FEEDBACK, sender_name=store.get('store_name'),
                store_id=store.objectId, body=body)
            # add the created reply to the store's sent messages relation
            store.add_relation("SentMessages_", [msg.objectId])
            # set feedback Reply pointer to message and update it
            feedback.set('Reply', msg.objectId)
            feedback.update()

            # store the updated feedback
            messages_received_list.pop(i_remove)
            messages_received_list.insert(i_remove, feedback)
            request.session['messages_received_list'] =\
                messages_received_list

            # save the session now! cloud_call may take a bit!
            request.session.save()

            # make the cloud call
            cloud_call(
                "retailer_message", {
                    "store_id": store.objectId,
                    "store_name": store.get('store_name'),
                    "message_id": feedback.objectId,
                    "filter": 'one',
                    "patron_id": feedback.get('patron_id'),
                    "feedback_reply_body": body,
                })

            # notify other tabs/browsers logged into the same store
            # about the newly created message.
            comet_receive(
                store.objectId, {
                    COMET_RECEIVE_KEY_NAME: COMET_RECEIVE_KEY,
                    "newMessage": feedback.jsonify()
                })

            # make sure we have the latest session to save!
            request.session.clear()
            request.session.update(SessionStore(request.session.session_key))

            return redirect(reverse('feedback_details',
                args=(feedback.objectId,)) + "?%s" %\
                urllib.urlencode({'success':'Reply has been sent.'}))

    else:
        # user navigated to this page
        if feedback.get("Reply"):
            # if the user manually tweaks the url, then s/he might be
            # able to reply to a feedback that already has a reply.
            return redirect(reverse('feedback_details',
                args=(feedback.objectId,)) + "?%s" %\
                urllib.urlencode({'error':'Cannot reply more than once.'}))

    # update store session cache
    request.session['store'] = store
    data['feedback'] = feedback

    # store the updated feedback
    messages_received_list.pop(i_remove)
    messages_received_list.insert(i_remove, feedback)
    request.session['messages_received_list'] =\
        messages_received_list

    return render(request, 'manage/feedback_reply.djhtml', data)
コード例 #9
0
ファイル: views.py プロジェクト: mjhshin/repunch_web
def edit(request, message_id):
    """
    Render the message edit template for a new message and handles
    send message forms.
    """
    data = {'messages_nav': True, 'message_id': message_id, "filters": FILTERS}

    store = SESSION.get_store(request.session)
    # number of patron stores
    mp = SESSION.get_patronStore_count(request.session)
    # make sure cache attr is None for future queries!
    store.patronStores = None

    data['mp_slider_value'] = int(ceil(float(mp) * 0.50))
    data['mp_slider_min'] = 1
    data['mp_slider_max'] = mp

    # redirect if no patrons
    if not store.get("patronStores", count=1, limit=0):
        return redirect(reverse("messages_index"))

    # user submitted a form by form submission through POST request
    # or user is coming from an upgrade sequence from subscription_update
    if request.method == 'POST' or (request.method == "GET" and\
        request.GET.get("send_message") and "message_b4_upgrade" in\
        request.session):

        if request.method == "GET":
            # user is coming from an upgrade sequence from subscription_update
            postDict = request.session['message_b4_upgrade'].copy()
            # cleanup temp vars in session
            del request.session['message_b4_upgrade']
            del request.session['from_limit_reached']

        else:
            # user submitted a form by form submission through POST request
            postDict = request.POST.dict().copy()

        # populate a message form with the POST data for validation
        form = MessageForm(postDict)

        if form.is_valid():
            # form is valid so continue to send the message
            subscription = SESSION.get_subscription(request.session)
            subType = subscription.get('subscriptionType')

            # refresh the message count - make sure we get the one in the cloud
            if 'message_count' in request.session:
                del request.session['message_count']
            message_count = SESSION.get_message_count(request.session)

            # get the max_messages from the user's subscriptionType
            # or the highest level if god_mode is on
            if subscription.god_mode:
                max_messages = sub_type[2]['max_messages']
            else:
                max_messages = sub_type[subType]['max_messages']

            # limit is reached if the amount of messages sent this
            # billing cycle passed the amount for that subscription type
            limit_reached = message_count >= max_messages

            # We always enforce the limit when we are in production
            # otherwise, we ignore it if we have message_limit_off in our session
            if limit_reached and (PRODUCTION_SERVER or\
                (not PRODUCTION_SERVER and "message_limit_off" not in request.session)):

                data['limit_reached'] = limit_reached

                # not the highest level of subscription so an upgrade
                # is still possible
                if subType != 2:
                    # save the dict to the session
                    request.session['message_b4_upgrade'] =\
                        request.POST.dict().copy()

                # the highest level of subscription so no more
                # upgrades can occur - therefore maxed_out
                elif subType == 2:
                    data['maxed_out'] = True

            else:
                # limit has not yet been reached - send the message
                # build the message from session and POST data
                message = Message(\
                    sender_name=store.get('store_name'),
                    store_id=store.objectId
                )
                message.update_locally(postDict, False)

                # check if attach offer is selected
                if 'attach_offer' in postDict:
                    # message has an offer - extract it from the post
                    # post data ensuring proper datetime format
                    d = parser.parse(postDict['date_offer_expiration'])
                    d = make_aware_to_utc(
                        d, SESSION.get_store_timezone(request.session))
                    message.set('date_offer_expiration', d)
                    message.set('message_type', OFFER)

                else:
                    # make sure to delete offer information in the case
                    # that attach offer is not checked but the form
                    # submitted still contained offer information
                    message.set('offer_title', None)
                    message.set('date_offer_expiration', None)
                    message.set('message_type', BASIC)

                # actually create the message to Parse
                message.create()

                # put the message in the template context for rendering
                data['message'] = message
                # add to the store's relation
                store.add_relation("SentMessages_", [message.objectId])

                # prepare the parameters for the cloud call
                params = {
                    "store_id": store.objectId,
                    "store_name": store.get('store_name'),
                    "subject": message.get('subject'),
                    "message_id": message.objectId,
                    "filter": message.filter,
                }

                # process the filter option
                if message.filter == "idle":
                    # pass in the correct idle_date which is today
                    # minus the days specified by idle_latency
                    idle_days = postDict['idle_latency']
                    d = timezone.now() + relativedelta(days=\
                        -1*int(idle_days))
                    params.update({"idle_date": d.isoformat()})

                elif message.filter == "most_loyal":
                    # pass in the number of patrons
                    params.update({"num_patrons": postDict['num_patrons']})

                # update store and message_count in session cache
                request.session['message_count'] = message_count
                request.session['store'] = store
                # save session- cloud_call may take a while!
                request.session.save()

                # make the cloud call
                res = cloud_call("retailer_message", params)
                if "error" not in res and res.get("result"):
                    message.set("receiver_count",
                                res.get("result").get("receiver_count"))

                # notify other tabs and windows that are logged into
                # this store about the new message sent.
                payload = {
                    COMET_RECEIVE_KEY_NAME: COMET_RECEIVE_KEY,
                    "newMessage": message.jsonify()
                }
                comet_receive(store.objectId, payload)

                # Note that the new message is saved in comet_receive
                # make sure we have the latest session to save!
                request.session.clear()
                request.session.update(
                    SessionStore(request.session.session_key))

                return HttpResponseRedirect(message.get_absolute_url())

        elif 'num_patrons' in form.errors:
            # form is invalid due to the number of patrons input
            # for most_loyal filter
            data['error'] = "Number of customers must be a "+\
                                "whole number and greater than 0."

        else:
            # form has some errors
            data['error'] = "The form you submitted has errors."

    else:
        # check if the incoming request is for an account upgrade
        if request.GET.get("do_upgrade"):
            # flag the upgrade view
            request.session["from_limit_reached"] = True
            # redirect to upgrade account
            return HttpResponseRedirect(reverse("subscription_update") +\
                "?do_upgrade=1")

        if message_id in (0, '0'):
            # this is a new message so just instantiate a new form
            form = MessageForm()

        else:
            # this is an existing message that the user wants to view

            # inserting this success and error message into the template
            # should be done in a cleaner way - this was done by the
            # first guy. I just didn't bother changing it.
            if request.GET.get("error"):
                data['error'] = request.GET.get("error")
            if request.GET.get("success"):
                data['success'] = request.GET.get("success")

            # get from the messages_sent_list in session cache
            messages_sent_list = SESSION.get_messages_sent_list(\
                request.session)
            for m in messages_sent_list:
                if m.objectId == message_id:
                    data['message'] = m

            if data['message']:
                # message is found so fill up the form with its data
                form = MessageForm(data['message'].__dict__.copy())

            else:
                # message not found so just instantiate a new form
                form = MessageForm()

    # update store session cache
    request.session['store'] = store

    # inject the form in the template context for rendering
    data['form'] = form

    return render(request, 'manage/message_edit.djhtml', data)