I am having a "send email" functionality in my application which sends email to the email addresses.
Later a new functionality is added where when the user checks on "Send email later" radio button, selects date and time and clicks on send email button so that the email is sent at particular time.
For this I added a field into database with column "send_reports_at", added to controller and required actions.
The date time is stored as : "2016-11-01 16:15".
How to add the condition of sending email based on the date time in my application(I am new to delayed job and all)?
Please help.
This is my view:
<%= f.input :additional_emails, :label => false, :input_html => {:id => 'sponge_contacts', :placeholder => 'Separate emails by comma', :class => 'deliver_page_email', :type => 'text', :rows => 2, :style=> 'width:300px; border-color:#ccc; font-size:13px; padding:10px 0 0 10px; width: 295px; height: 110px; resize: none;'} %>
<input type="radio" id="send_email_0" name="send_email" value="now" checked> Send email now<br>
<input type="radio" id="send_email_1" name="send_email" value="later"> Send email later<br>
<%= f.input :send_reports_at,:label => false, :input_html => {:placeholder => 'Click here to select date and times', :class => 'deliver_page_email', :type => 'text', :rows => 2} %>
<% content_for :javascript do %>
<script type="text/javascript">
$( function() {
$( "#report_send_reports_at" ).datepicker();
} );
$(document).ready(function() {
$("#report_send_reports_at").hide();
$("#send_email_0, #send_email_1").bind('change click',function(){
toggleResult();
});
});
function toggleResult(){
result = $("[name='send_email']:checked").val();
if(result == "later"){
$("#report_send_reports_at").show();
}else{
$("#report_send_reports_at").hide();
}
}
</script>
<% end %>
<% end %>
<%= link_to "Send Now", '#', :class => "pink_button _round_5", :id => 'send_now_button' %>
This is my controller method:
def send_report_email
send_to_agents = params.has_key?("send_to_agents") && params["send_to_agents"] == "true"
if #report.photos.empty?
Screenshot.delay.new(#user.id, #report.id, Rails.application.config.custom.indicator_screenshot_bucket)
else
Screenshot.delay.new(#user.id, #report.id, "photo_screenshots")
end
Screenshot.delay.new(#user.id, #report.id, Rails.application.config.custom.report_screenshot_bucket)
if #report.update_attributes(params[:report])
set_photo_position(false)
#report.save
if send_to_agents
#report.update_attribute(:duplicable, true)
#good_emails, #bad_emails, #unsubscribed_emails = #user.account.users.map(&:email), [], []
else
#good_emails, #bad_emails, #unsubscribed_emails = filter_emails(#report.additional_emails)
#user.delay.add_new_contacts(#good_emails)
end
#good_emails.each do |email|
send_to_agents == true ? ReportMailer.delay.additional_emails(email, #user, #report, "A new report is available: #{#report.title}") : ReportMailer.delay.additional_emails(email, #user, #report)
end
ReportMailer.delay.report_sent(#user, #report, #good_emails, #bad_emails, #unsubscribed_emails)
end
respond_to do |format|
format.json { render :json => { :success => true, :report_id => #report.id, :redirect => user_reports_url(current_user), :notice => 'Report was successfully sent!' } }
end
end
You could write a function (for instance a class method for ReportMailer) that sends all of the email whose scheduled time matches or is less than the current time, then set a cron job to use rails runner to run that function as often as necessary.
Related
I am trying to process a payment using a simple stripe charge, the user must pay a quantity in the website through a form and, basically, I don´t know why i am not getting the token back, I think my javascript is not being executed actually. Here is the code:
This is the form placed in order#new (the form view)
:javascript
Stripe.setPublishableKey("<%= ENV['STRIPE_TEST_PUBLISHABLE_KEY] %>");
.container.body-content
%h2
Complete order:
= #cart.name
%table.table.table-items
%tr
%th Design name
%th Quantity
%th Price
- #cart.cart_items.each do |c|
%tr
%td= c.design.name
%td= c.quantity
%td= c.design.price
%tr
%th Total price
%th
%th= #total_price
= simple_form_for(#order, html: { role: "form", class: "cc_form" }) do |f|
= f.simple_fields_for( :payment ) do |p|
.row.col-md-12
.form-group.col-md-4.no-left-padding
= p.input :card_number,
label: "Card Number",
label_html: { data: { stripe: "label" } },
input_html: { required: "true", data: { stripe: "number" }, class: "form-control" }
.form-group.col-md-2
= p.input :card_cvv,
label: "Card CVV",
label_html: { data: { stripe: 'label' } },
input_html: { required: "true", data: { stripe: "cvv" }, class: "form-control" }
.form-group.col-md-6
.col-md-12
= p.label :card_expires, "Card expires", data: { stripe: 'label' }
.col-md-3
= p.select :card_expires_month, options_for_select(Payment.month_options), { include_blank: 'Month' }, data: { stripe: "exp-month" }, class: "form-control", required: true
.col-md-3
= p.select :card_expires_year, options_for_select(Payment.year_options.push), { include_blank: 'Year' }, data: { stripe: "exp-year" }, class: "form-control", required: true
= f.hidden_field :cart_id, :value => #cart.id
= f.hidden_field_tag 'cart', #cart.id
= f.hidden_field_tag 'total_price', #total_price
= f.button :submit, "Pay and finish order", class: "btn btn-login"
This is orders_controller.rb:
class OrdersController < ApplicationController
include ApplicationHelper
def index
end
def new
#order = current_user.orders.build
#cart = Cart.find(params[:format])
#payment = #order.build_payment
#total_price = get_total_price_for_navigation_bar
end
def create
#order = current_user.orders.build(order_params)
#cart = Cart.find(params[:cart])
#payment = #order.build_payment
#payment.user_id = current_user.id
process_payment(params[:total_price])
if payment.save
if #order.save
#cart.purchased = true
#cart.total_price = params[:total_price]
#cart.save
flash[:success] = "Order created"
redirect_to orders_path
else
flash[:danger] = "Order couldn´t be saved, please try again"
render :new
end
else
flash[:danger] = "There was a problem processing your payment, please try again"
render :new
end
end
private
def order_params
params.require(:order).permit(:cart_id)
end
def process_payment(amount)
#byebug
token = params[:stripeToken]
byebug
# Create a charge: this will charge the user's card
begin
charge = Stripe::Charge.create( :amount => amount * 100, :currency => "eur", :source => token, :description => "Example charge")
rescue Stripe::CardError => e
# The card has been declined
end
end
end
and to process the payment I have created credit_card_form.js (of course under assets -> javascripts (I have also removed the turbolinks from application.js )
$(document).ready(function(){
var show_error, stripeResponseHandler, submitHandler;
submitHandler = function(event){
var $form = $(event.target);
$form.find("input[type=submit]").prop("disabled", true);
//If stripe was correctly initialized this will create a token using the credit card info
if(Stripe){
Stripe.card.createToken($form, stripeResponseHandler);
} else {
show_error("Failed to load credit card processing functionality. Please reload this page in your browser.")
}
return false;
};
$(".cc_form").on('submit', submitHandler);
stripeResponseHandler = function(status, response){
var token, $form;
$form = $('.cc_form');
if (response.error) {
console.log(response.error.message);
show_error(response.error.message);
$form.find("input[type=submit]").prop("disabled", false);
} else {
token = response.id;
$form.append($('<input type="hidden" name="stripeToken">').val(token));
$form.get(0).submit();
}
return false;
};
show_error = function(message){
if($("#flash-messages").size() < 1){
$('div.container.main div:first').prepend("<div id='flash-messages'></div>")
}
$("#flash-messages").html('<div class="alert alert-warning"><a class="close" data-dismiss="alert">x</a><div id="flash_alert">' + message + '</div></div>');
$('.alert').delay(5000).fadeOut(3000);
return false;
};
});
When I try to process a payment I never receive the token in the order#create method, so I think that the javascript is not executing
When I inspect variables in terminal I see that the token is not added to the form as a param, as I am suppose to append in stripeResponseHandler in credit_card_form.js this is the output I see when I inspect variables:
(byebug) token
nil
(byebug) params
{"utf8"=>"✓", "authenticity_token"=>"ps963bnlJwbayybIgXVAu8xQI3L6BneUK6qg5k9U9BV7XL+3M+Bl+OVJqJGNrcMHLAjhjvxOkOlhyig9Sh5Cdw==", "order"=>{"payment_attributes"=>{"card_number"=>"4012888888881881", "card_cvv"=>"123", "card_expires_month"=>"3", "card_expires_year"=>"2017"}, "cart_id"=>"9"}, "cart"=>"9", "total_price"=>"390.0", "controller"=>"orders", "action"=>"create"}
(byebug)
Well, I don´t know if I am not seing something stupid or I am completely wrong in my approach, any suggestion will be appreciated.
Thanks in advance
Antonio
[Update: Problem solved]
After several hours, I found what was the problem, wasn´t the code itself, the problem was HAML actually, precisely the way haml interpretes the form id or the class, I don´t know exactly why but I have changed from haml to .erb file and both the customer creation and the stripe charge are processed correctly. For what i´ve seen, using that haml version of the form stripeResponseHandler wasn´t correctly executed (don´t ask me why, I am not so sure, I just know the form wasn´t updated correctly and the token was not included as a param as I wanted in order to process the charge) that is why the charge wasn´t created successfully.
Hope it helps to someone else.
Regards and thanks to u all.
I have Client model and Contact model. On the Client page, I put "Add to Contact" button to save it on the contact model.
I have this code on my client page:
= form_for(#contact, remote: true, html: { class: 'form-horizontal ajax-form add-to-contact', style: 'margin-bottom: 0;', 'data-model-name' => 'contact'}) do |f|
= f.text_field :type, :value => 'clients'
= f.text_field :client_id, :value => client.id
= f.submit "Add to Contact", class: 'btn btn-success btn-submit-add-to-contact'
clients_controler.rb
def index
#contact = Contact.new(params[:client_id], params[:type])
end
contacts_controller.rb
def create
#contact = Contact.new(contact_params)
respond_to do |format|
if #contact.save
format.js {}
else
format.json { render json: #contact.errors, status: :unprocessable_entity }
end
end
end
And I have coffeesript code that when I submit it, it will save to contact model:
$(document).on "click", ".btn-submit-add-to-contact", ->
$(this).prop "disabled", true
$(this).val "Added to Contacts!"
$(".add-to-contact").submit()
But there's a problem on saving. All of my clients save, as in they're looping and automatically saving although I'm not submitting other client. Please help.
You should remove remote: true if you are adding you own Ajax functionality.
Also you should prevent the default click action or the browser will submit the form twice.
$(document).on "click", ".btn-submit-add-to-contact", ->(e)
$(this).prop "disabled", true
$(this).val "Added to Contacts!"
$(".add-to-contact").submit()
e.preventDefault()
If you are using jquery-ujs you should listen for the completed ajax call instead:
$(document).ready ->
$("form").on("ajax:success", (e, data, status, xhr) ->
I got this.
I've modified my JS:
$(document).on "click", ".btn-submit-add-to-contact", ->
$(this).prop "disabled", true
$(this).val "Added to Contacts!"
contact_form = $(this).closest('.add-to-contact-form').find('.ajax-form')
contact_form.submit()
return
And I put class before my form:
.add-to-contact-form
= form_for(#contact, remote: true, html: { class: 'form-horizontal ajax-form add-to-contact', style: 'margin-bottom: 0;', 'data-model-name' => 'contact'}) do |f|
= f.text_field :type, :value => 'clients'
= f.text_field :client_id, :value => client.id
= f.submit "Add to Contact", class: 'btn btn-success btn-submit-add-to-contact'
I use .closest and it works fine to me.
Thanks for helping me!
How can I use simple_form to filter a field, based on a previous fields value?
For instance, I have an Opportunities form, with two fields, Company and Contact.
Company Field:
<div class="form-group">
<%= f.association :company, collection: Company.all.order(:account), prompt: "", :label_method => :account, :value_method => :id %>
</div>
Contact Field:
<div class="form-group">
<%= f.association :contact, collection: Contact.all.order(:first_name), prompt: "", :label_method => lambda { |contact| "#{contact.first_name} #{contact.last_name}" }, :value_method => :id %>
</div>
Here is what I want to do: If I select a company called "Deviant" from the Company field above, I want the Contact field to only display those contacts associated with the company called "Deviant".
I am trying something like this, but can't get it to work:
<div class="form-group">
<%= f.association :contact, collection: Contact.where("company_id = ?", params[:id]), prompt: "", :label_method => lambda { |contact| "#{contact.first_name} #{contact.last_name}" }, :value_method => :id %>
</div>
I don't know how to reference the value in the Company field.
How can I do this?
Thanks.
Update
Anyone? Surely this must be possible. This is a key functionality in any form. I would hope I don't need jQuery or something.
I think the best approach is to use ajax requests to update your contacts collection dinamically whenever the company's selected value is changed.
First you'll need an action in your contacts controller:
app/controllers/contacts_controller.rb
class ContactsController < ApplicationController
def contacts_list
if params[:company_id]
#contacts = Contact.where(company_id: params[:company_id])
else
#contacts = Contact.all
end
respond_with(#contacts) do |format|
format.json { render :json => #contacts.to_json(:only => [:id, :first_name, :last_name]) }
end
end
end
Add this to your routes:
config/routes.rb
post 'contacts_list' => "contacts#contacts_list", as: :contacts_list
Then use the coffeescript code bellow to populate your contacts' collection:
app/assets/javasctipts/companies.js.coffee
$(document).ready ->
if $("#opportunity_company_id")
populate_contacts()
$("#opportunity_company_id").change ->
populate_contacts()
populate_contacts = ->
$contacts_select = $("select#opportunity_contact_id")
$contacts_select.attr "disabled", "disabled"
company_id = $("select#opportunity_company_id").val()
if company_id is ""
$contacts_select.html "<option value=\"\">(select the company first)</option>"
else
$contacts_select.html "<option value=\"\">(loading contacts...)</option>"
data = {company_id: company_id}
data[window._auth_token_name] = window._auth_token
$.ajax "/contacts_list",
type: "post"
dataType: "json"
data: data
success: (contacts) ->
_html = '<option value="">Select the contact:</option>'
_html += '<option value="'+contact.id+'">'+contact.first_name + ' ' + contact.last_name + '</option>' for contact in contacts
$contacts_select.html _html
$contacts_select.removeAttr "disabled"
error: ->
alert 'Error trying to load contacts.'
Finally, inside your html's head tag:
<% if protect_against_forgery? %>
<script>
window._auth_token_name = "<%= request_forgery_protection_token %>";
window._auth_token = "<%= form_authenticity_token %>";
</script>
<% end %>
Hope it helps...
update:
Add the following line to your ApplicationController (app/controllers/application_controller.rb):
respond_to :html, :xml, :json, :js
Rails 3.2
jQuery-Rails
I've searched all over and I've only found js ways to update a partial or add a partial via JS. I've had no luck with this one. Here is the issue:
I have a list of referrals on a page, the referrals are posted on the index page as partials. The referral box has a reply button and a count of how many replies per referral. Statically I had it working but I'm getting no luck with updating the referral box with the new count and replacing the reply button with an icon. The is getting to the database but I'm screwing something up with the refresh of the box. Help please!
Do I use locals to render the new variables?
Should I remove my if statements from the partial and just use the js.erb file to determine what to show?
Reply controller:
class RepliesController < ApplicationController
respond_to :html, :js
def new
#referral = Referral.find(params[:referral_id])
#reply = #referral.replies.new(:user_id => params[:user_id], :referral_id => params[:referral_id])
if #reply.save
format.html { notice: 'Replied' }
respond_with(#referral, :location => referrals_path)
end
end
end
_referral partial:
.referralBox.cornerShadow{:id => "Referral#{referral.id}"}
- if current_user == referral.user or current_user.role == 'administrator'
= link_to '<i class="icon-pencil icon-large icon-grey" rel="tooltip" title="Edit"></i>'.html_safe, edit_referral_path(referral), class: "referralEdit"
= link_to '<i class="icon-remove icon-large icon-grey" rel="tooltip" title="Delete"></i>'.html_safe, referral, method: :delete, data: { confirm: 'Are you sure?' }, class: "referralClose"
.referralProfile
= link_to "#{image_tag(referral.user.image.url, :class => "img-circle img-border border-white", :style => "thumb")}".html_safe, referral.user
%ul.unstyled.inline
%li
= referral.description
- unless referral.replies.count == 0
- if referral.user == current_user
%i.icon-comments.icon-large{"rel" => "tooltip", "title" => "Replies"}
= referral.replies.count
- else
%i.icon-comments.icon-large.orange{"rel" => "tooltip", "title" => "Replies"}
= referral.replies.count
- unless current_user == referral.user
- if referral.replies.any?
%i.icon-ok.icon-large.pull-right.orange{"rel" => "tooltip", "title" => "Replied"}
- else
= link_to '<i class="icon-ok icon-large pull-right icon-grey" rel="tooltip" title="Reply"> Reply</i>'.html_safe, new_referral_reply_path(:referral_id => referral.id, :user_id => current_user.id), :id => "ReplySubmit", :remote => true
new.js.erb view
$(".referralBox").html("<%= j(render(:partial => "#referral")) %>");
application.js
jQuery.ajaxSetup({
'beforeSend': function (xhr) {xhr.setRequestHeader("Accept", "text/javascript")}
});
I have a view which contain multiple links:
<% a.each do |q| %>
<%= link_to "stock it",
{ :action => "stock",
:qid => q.question_id,
:qur => q.question_answers_url,
:qti => q.title } ,
:remote => true %>
<div id="<%= "stock" + q.question_id.to_s %>"></div>
<% end %>
Each link generate AJAX-request. Here is a controller:
def stock
if(!Later.where(:question_id => params[:qid]).exists?)
later = Later.new(:question_id => params[:qid], :name => params[:qti], :url => params[:qur])
later.save
end
respond_to do |format|
format.js { render :layout=>false }
end
end
Now return to the view. Each link has a 'div' with unique id='stock'. When user press the link I need to add text to specific div with corresponding id.
I have a stock.js.erb file:
$("#stock<number>").html("some text");
How can I pass div-id to stock.js.erb and how can I use it ?
Common use is to add object.id to your DOM id. That what you exactly did:
<div id="<%= "stock_#{q.question_id}" %>"></div>
Then in your controller you shoud define your question_id or your exact question:
def stock
if(!Later.where(:question_id => params[:qid]).exists?)
later = Later.new(:question_id => params[:qid], :name => params[:qti], :url => params[:qur])
later.save
end
#question_id = params[:qid]
end
Now it will be shared with your stock.js.erb file:
$("#stock_<%= #question_id %>").html("some text");