How can I switch the currency of a user in spree? - ruby-on-rails

In my spree store I have changed the currency settings from USD to AUD and this seems to work mostly but for the existing users when and item is added to the cart the cart shows the old USD price despite showing the new AUD price before adding to cart.
Inspecting the order in the rails console shows the order is set to USD still, new users have their orders set to AUD. How can I change it so all users are now on the new currency?

In order.rb there is a before_validation
before_validation :set_currency
and code for this method is
def set_currency
self.currency = Spree::Config[:currency] if self[:currency].nil?
end
here currency is set to default currency only if it's not present, So if you want all the active orders to get modified with the new currency that you set through general settings, you can modify the above method to ensure it always set currency before validation.
def set_currency
self.currency = Spree::Config[:currency]
end
Please let me know if you still face any issues

Related

How do I calculate values for the current user in ruby on rails?

I have an application with a series of tests (FirstTest, SecondTest etc.)
Each test has a calculation set out its relevant model that gets calculated before being saved to the database set out like this:
#first_test.rb
before_save :calculate_total
private
def calculate_total
...
end
I then have an index page for each user (welcome/index) which displays the current user's results for each test. This all works fine, however I want to work out various other things such as each users average score overall etc.
Is it possible to access the current user from the welcome model?
Currently my welcome.rb is accessing the data follows:
#welcome.rb
def self.total
FirstTest.last.total
end
This obviously access the last overall test NOT the last test from the current user.
I feel like I may have just laid the whole application out in a fairly unintelligent manner...
Thanks in advance x
Well you need to save user_id in a column for each record in FirstTest. Then you can find the total for current user
FirstTest.where(:user_id => current_user.id).last.total

Making posts inactive after a date and time

I've to make posts inactive after a given date and time by the user who creates these posts. I've added a boolean field "published" to make a post active or unactive.
If the post is active, every visitor will see the post. If it's inactive, the post will be seen in the user dashboard as inactive.
For you guys what is the best way to make a post inactive after the given datetime passed? That should be automatic but I don't think the suitable way is using Active Job and ;
Check all posts in the db if active,
If active, compare the given datetime and current datetime
If needed, make it inactive
I'm using heroku, so that'll make my worker busy all the time.
If you simply plan to fetch and display posts, rather than setting the boolean value, you could just add a scope to the model:
scope :published, -> { where('publish_at < ?', Time.now) }
And use like this Post.published
Let me know if this helps.
Update 1:
If you need to determine if a post is active or not, add a method to the model like this,
def active?
self.publish_at < Time.now
end
You can do some things:
Option 1:
Based in the #jawad-khawaja answer, I think a better approach is to use expired_at instead of published_at because for me, a publish date is a date when a post is available for people. This way the user can define an expiration date for his own post (not the same publish date).
Here some example how to you can get active/inactive posts based on its expiration date
# active posts
scope :published, -> { where('expired_at > ?', Time.now) }
# inactive posts
scope :unpublished, -> { where('expired_at < ?', Time.now) }
Option 2:
If you have an attribute published as boolean and you really need mark it automatically, the option is to use whenever gem
CONS for this option:
You will have two attributes representing the same thing: published as boolean and expiration_datetime as datetime
If the minimum unit for an expiration date is a minute, you need to check every minute if every not-expired post enter to the expired state. And you will have probably an overload for your server.
Conclusion:
My recommended way is to choose the option 1.

ruby on rails pairing users in database

How can I write a code in Ruby on rails that picks user X from my database( let say I have a column called 'taskdone' which accepts only boolean values ... And user X is true in such column) such that when a new user signs up, user X is displayed on his profile. And the new user is given a task to complete. If he
completes it successfully user X can confirm from his own account that the new user has completed his task by clicking a button which writes a value of true to the new users paid 'task done ' column. And after user X has confirmed four people, his value in the column should go back to false. It's quite complicated please I need someone to help am frustrated searching Google without answers
You can do this in two ways
1- If you need the information about "which user confirms another user" You can create an association to hold for each user X which other users he has confirmed.
2 - If you won't use these info you can just create a column that counts the number of confirmed users in the Users tabel.
In both cases, After a user confirms another user make a check if he has confirmed 4 users or not using the callback after create and then update the taskdone column.
after_create :update_task_done
In the first way do
def update_task_done
if self.confirmed_users.count == 4
self.update(taskdone: false)
end
end
In the second way
def update_task_done
if self.confirmed_users_count == 4 # notice this is column.
self.update(taskdone: false)
end
end

rails can you reference a model within a model?

I seem to have run into a problem with trying to use a model in another model in Rails.
I am pulling a list of users from Active Directory with LDAP in a dropdown. I want to parse the cn that I get from Ldap into a firstname and lastname.
The problem I am running into is that I need to find a record in the users model. The parsing is being done in observations.rb.
Observation.rb:
def parse_employee
#emp_name = '' #initialize
self.employee_raw = self.employee_raw[2...-2] # get rid of the quotes and brackets
#emp_name = self.employee_raw.split(' ') # split first/last names
#emp_first_name = #emp_name[0] #Grab the first name
#emp_last_name = #emp_name[1] # grab the surname
#user = User.where("last_name like ?", #emp_last_name)
self.employee_id = #user.id
end
I've played with this quite a bit and it appears that I can't reference other models from within a model.
To sum up, what I am trying to do is
1. Have the user select the appropriate person from a dropdown that is pulled via LDAP from active directory.
2. Use the first and last names to find the appropriate user in my user table (Right now I'm just trying to get it to work with the last name as that is unique enough)
3. When I find the correct user in the user table, enter that id in the employee_id field in my observations table.

django admin permissions to modify model's attributes

we are using django to develop a customer-management application, and we need to set permissions to an agent whether he/she can edit the customer's attributes ().
for example,
if i have a model:
class Customer(models.Model):
# basic information
name = models.CharField(max_length=150) # the name of this customer
date = models.DateField(auto_now_add=True) # the date that this customer is created
# personal information
citizen_id = models.BigIntegerField(blank=True)
phone = models.BigIntegerField(max_length=20, blank=True)
work = models.CharField(max_length=100, blank=True)
address = models.CharField(max_length=300, blank=True)
bank_card = models.BigIntegerField()
# installation detail
primary = models.IntegerField(default=0)
secondary = models.IntegerField(default=0)
region = models.ForeignKey(Region) # the region that this customer currently lives in
type = models.ForeignKey(Type) # the installation type
group = models.ForeignKey(Group)
STATUS_CHOICES = (
('Active', 'Active'),
('Inactive', 'Inactive'),
('Transfered', 'Transfered'),
('Closed', 'Closed'),
('Suspended', 'Suspended'),
('Cancelled', 'Cancelled'),
)
status = models.CharField(max_length=40, choices=STATUS_CHOICES)
and I want to be able to set the permissions for editing some of the fields, but the current permission system only allow you add/change/delete a model instance, where the "change" allows an user to edit all the attributes in that model, which is not what we really want.
user A can edit phone, address, work and citizen_id
user B can only edit phone and address,
user C can edit citizen_id, .....
etc...
and I want to be able to set different permissions
Is it possible to make this happen? It'd be really helpful if I could use the django admin system to manage agents and customers.
=======================
thank you so much for FallenAngel's reply.
I think that's exactly what we want.
this is what I've tried,
in admin.py
class CustomerAdmin(admin.ModelAdmin):
def change_view(self, request, object_id, extra_context=None):
agent = Agent.object.get(user=request.user)
permitted_fields = agent.permitted_fields # assume i have this setup...
self.readonly_fields = get_not_permitted_fields(premitted_fields) # assume I have this function written somewhere
return super(CustomerAdmin, self).change_view(request, object_id,
extra_context=None)
this works exactly that way I want: for the not permitted fields, set them to readonly...
thanks again,
That is possible... You must use django admin methods as they described in here... You must define add_view, change_view and changelist_view functions...
You must also find a way to group users (groups might be a good way, or you can use permissions). I create a model that extends User model, but you can find your own way...
Second write basic add, change and listview founctions like:
class CustomerAdmin(admin.ModelAdmin):
list_display= ["fields that will be used for all users"]
def changelist_view(self, request, extra_context=None):
if request.user == "type a":
self.list_display.extend["list of other fields"]
return super(CustomerAdmin, self).changelist_view(request, extra_context)
You must specify add, change (and changelist if required) views and handle each user type. Then Django will show related fields for the user. You extend list_display, fileds, exclude, list_filter and such django admin field display methods...

Resources