I've just uploaded a new release of the Redmine Budget plugin. The Budget plugin is a plugin for Redmine to manage the set of deliverables for each project, automatically calculating key performance indicators. This is a long awaited release that will fix many of the outstanding bugs and incompatibilities that have cropped up.
Download
The plugin can be download from the Little Stream Software project or from GitHub.
Changes
You can see more details on the Changelog and Roadmap pages.
Help
If you need help, my Redmine bug tracker is open to the public and you are welcome to ask for help there.
If you are currently working on a Redmine plugin and need help or have an idea for a plugin you would like developed, please contact me. My company, Little Stream Software, specializes in the development of custom Redmine features and Redmine plugins.
Eric
Tagged: open source plugin redmine redmine plugins ruby on rails
I've got a new Redmine plugin I'm Open Sourcing, the Redmine Rate plugin. This plugin will store billable rates for Users and will relate the amount of time worked to a specific amount. This was extracted out of the Budget plugin, once it was discovered that tracking historic rates was needed. Now if someone's billable rate changes, the plugin will adapt to that change without affecting past transactions.
Features
- Track rates for a user based on
- Date Rate came into effect and
- the Project
- Store historic rate amounts
- Lock rates to preserve historic calculations
- Rate.for API for other plugins
- Integration with the Billing plugin
- Integration with the Budget plugin
Getting the plugin
A copy of the plugin can be downloaded from Little Stream Software or from GitHub
Installation and Setup
This plugin will convert existing data in the Budget or Billing plugins. To prevent data loss, I recommend you read the README that is included with the release.
Usage
There are a couple of ways to use this plugin:
Enter new rate for a project
There are two ways to set rates for a Member of a Project.
- Browse to the Project Settings page
- Select the Members tab
- Enter the rate for the Member and click the set Rate
Alternatively, Rates can be set in the User Administration panel
- Browse to the Administration panel
- Select Users
- Select the specific user to add a rate for
- Select the Membership tab and enter a rate for each project
- Or, select the Rate History and enter a new rate in the form
Enter default rate for a user
A default rate is a user's Rate that doesn't correspond to a specific project. It can be set in the User Administration panel:
- Browse to the Administration panel
- Select Users
- Select the specific user to add a rate for
- Select the Rate History and enter a new rate in the form, keep the Project field set to Default Rate.
Lock a Rate
Currently this feature is only available through the Rate API. A Rate will become locked once a valid TimeEntry is assigned to the Rate. This is used to make sure historical amounts are not changed.
License
This plugin is licensed under the GNU GPL v2.
Project help
If you need help you can contact me or create an issue in the Bug Tracker.
Thanks
I would like to thank Shane and Peter, Inc for sponsoring this plugin. If you find it useful, send your appreciation his way.
If you are currently working on a Redmine plugin and need help or have an idea for a plugin you would like developed, please contact me. My company, Little Stream Software, specializes in the development of custom Redmine features and Redmine plugins.
Eric
Tagged: open source redmine redmine plugins
I've been writing Redmine plugins since 2007 and one thing that stumped me was how to add new methods to Redmine's core classes and have them working in development. The standard Ruby on Rails way of including a module into the class works great except in development mode. Thanks to Thomas Löber, I found a way to overcome this error by making Ruby on Rails reload specific plugin classes.
Patching the core for fun and profit
I'm going to create a quick plugin that shows an example. Lets say you have a method called moo that you want to add to the Issue class. The standard Ruby on Rails plugin way would be to create a module and call Issue.send(:include).
# lib/my_moo_patch.rb
module MyMooPatch
def self.included(base)
base.send(:include, InstanceMethods)
end
module InstanceMethods
def moo
logger.info 'moo'
end
end
end
# init.rb
require 'my_moo_patch'
Issue.send(:include, MyMooPatch)
This is a pretty standard case and would be used anytime your plugin needs to relate to the core classes. To illustrate this example and some errors that are caused, I added a call to @issue.moo on the Issue show page. Typically you would use the Redmine Hooks to have Redmine run your plugin's code.
Running the code
Running in the production environment, everything works fine:
Processing IssuesController#show (for 127.0.0.1 at 2009-04-13 09:57:41) [GET]
Parameters: {"action"=>"show", "id"=>"1765", "controller"=>"issues"}
moo
Rendering template within layouts/base
Rendering issues/show.rhtml
Completed in 1037ms (View: 873, DB: 31) | 200 OK [http://localhost/issues/1765]
Processing IssuesController#show (for 127.0.0.1 at 2009-04-13 09:57:44) [GET]
Parameters: {"action"=>"show", "id"=>"1765", "controller"=>"issues"}
moo
Rendering template within layouts/base
Rendering issues/show.rhtml
Completed in 257ms (View: 173, DB: 17) | 200 OK [http://localhost/issues/1765]
But in development, the first request will work but the second request will now throw an exception:
# First request
Processing IssuesController#show (for 127.0.0.1 at 2009-04-13 09:59:32) [GET]
Parameters: {"action"=>"show", "id"=>"1765", "controller"=>"issues"}
moo
Rendering template within layouts/base
Rendering issues/show.rhtml
Completed in 1285ms (View: 990, DB: 24) | 200 OK [http://localhost/issues/1765]
# Second request
Processing IssuesController#show (for 127.0.0.1 at 2009-04-13 09:59:36) [GET]
Parameters: {"action"=>"show", "id"=>"1765", "controller"=>"issues"}
NoMethodError (undefined method `moo' for #<Issue:0xb4ab3d94>):
/vendor/rails/activerecord/lib/active_record/attribute_methods.rb:260:in `method_missing'
/app/controllers/issues_controller.rb:98:in `show'
<<snip>>
Rendering /home/edavis/dev/redmine/redmine-core/vendor/rails/actionpack/lib/action_controller/templates/rescues/layout.erb (internal_server_error)
Debugging the error
The NoMethodError is a standard error thrown by Ruby when a class doesn't have a method defined. But we defined Issue#moo in our plugin, so why is it not found? Lets take a look at what's happening in the Ruby debugger:
# First request
>> MyMooPatch.object_id
=> -621509448
>> @issue.class.object_id
=> -621657688
>> pp @issue.class.included_modules
[MyMooPatch::InstanceMethods,
MyMooPatch,
Redmine::Acts::ActivityProvider::InstanceMethods,
Redmine::Acts::Event::InstanceMethods,
Redmine::Acts::Searchable::InstanceMethods,
Redmine::Acts::Watchable::InstanceMethods,
Redmine::Acts::Customizable::InstanceMethods,
Redmine::Acts::Attachable::InstanceMethods,
Redmine::I18n,
Kernel]
=> nil
>> @issue.class.included_modules.include?(MyMooPatch)
=> true
Nothing out of the ordinary here. Issue has MyMooPatch included and the request processes successfully.
# Second request
>> MyMooPatch.object_id
=> -621509448 # Same id as above
>> @issue.class.object_id
=> -630808728 # Different id from above.
>> pp @issue.class.included_modules
[Redmine::Acts::ActivityProvider::InstanceMethods,
Redmine::Acts::Event::InstanceMethods,
Redmine::Acts::Searchable::InstanceMethods,
Redmine::Acts::Watchable::InstanceMethods,
Redmine::Acts::Customizable::InstanceMethods,
Redmine::Acts::Attachable::InstanceMethods,
Redmine::I18n,
Kernel]
=> nil
>> @issue.class.included_modules.include?(MyMooPatch)
=> false
But on the second request we notice something wrong. Issue no longer has MyMooPatch included and it also has a different class id from the last request. This means that something created a new Issue class object that is used instead of the original one. In development mode, Ruby on Rails reloads classes after each request so on the second request the Issue class was reloaded but our patch wasn't applied.
Wrapping our monkey-patch in a callback
Fortunately, Ruby on Rails provides a callback method we can use to add our module back, after a class is reloaded. It's called Dispatcher.to_prepare.
Add a preparation callback. Preparation callbacks are run before every
request in development mode, and before the first request in production
mode. (From: rails/actionpack/lib/action_controller/dispatcher.rb)
So we will need to change the way out module is included in Issue. Instead of just using the straight send, we need to wrap it in the Dispatcher.to_prepare method:
require 'dispatcher'
require 'my_moo_patch'
Dispatcher.to_prepare do
Issue.send(:include, MyMooPatch)
end
Now if we restart the Ruby on Rails server in development mode, all the requests should be successful.
Processing IssuesController#show (for 127.0.0.1 at 2009-04-13 10:42:58) [GET]
Parameters: {"action"=>"show", "id"=>"1765", "controller"=>"issues"}
moo
Rendering template within layouts/base
Rendering issues/show.rhtml
Completed in 1382ms (View: 1056, DB: 26) | 200 OK [http://localhost/issues/1765]
Processing IssuesController#show (for 127.0.0.1 at 2009-04-13 10:43:21) [GET]
Parameters: {"action"=>"show", "id"=>"1765", "controller"=>"issues"}
moo
Rendering template within layouts/base
Rendering issues/show.rhtml
Completed in 1266ms (View: 951, DB: 26) | 200 OK [http://localhost/issues/1765]
Processing IssuesController#show (for 127.0.0.1 at 2009-04-13 10:43:25) [GET]
Parameters: {"action"=>"show", "id"=>"1765", "controller"=>"issues"}
moo
Rendering template within layouts/base
Rendering issues/show.rhtml
Completed in 1210ms (View: 901, DB: 25) | 200 OK [http://localhost/issues/1765]
Success, our Issue is now mooing!
Summary
So if you write a Ruby on Rails or Redmine plugin that needs to patch the core, you should wrap your patches in Dispatcher.to_prepare so that they will work in development mode. I'll be converting all my plugins to use this pattern soon. If you would like to develop a patch for one yourself, fork one of my plugins on GitHub and sent me a pull request.
Eric
Tagged: plugins redmine ruby ruby on rails
I've just uploaded the latest release of the Redmine System Notification plugin. This is a plugin that will let Administrators send emails to a list of users to let them know of important events (e.g. downtime, upgrades). This release includes some new features for composing the notification, translations, and support for the latest stable and development versions of Redmine.
Download
The plugin can be download from the Little Stream Software project or from GitHub.
Changes
You can see more details on the Changelog and Roadmap pages.
Help
If you need help, my Redmine bug tracker is open to the public and you are welcome to ask for help there.
Eric
Tagged: open source plugin redmine redmine plugins ruby on rails
After a long wait, I've just uploaded a new release of the Redmine Customer plugin. This is a bug fix and translation release that should support the released version of Redmine as well as the latest trunk version.
Download
The plugin can be download from the Little Stream Software project or from GitHub.
Changes
You can see more details on the Changelog and Roadmap pages.
What's next
The next release should have some new features including the start of a CRM type system. If you have an idea for one, leave a comment here or open a feature request.
Help
If you need help, my Redmine bug tracker is open to the public and you are welcome to ask for help there.
Eric
Tagged: plugin redmine ruby on rails
I'm happy to announce that I've just uploaded a new release of the Redmine Bulk Time Entry plugin. This is a bug fix release that should support the released version of Redmine as well as the latest trunk version.
Download
The plugin can be download from the Little Stream Software project or from GitHub.
Changes
You can see more details on the Changelog and Roadmap pages.
What's next
The next release should have a couple of new features, including some User Interface updates to make entering time even faster. If you have an idea for one, leave a comment here or open a feature request.
Help
If you need help, my Redmine bug tracker is open to the public and you are welcome to ask for help there.
Eric
Tagged: open source redmine redmine plugins
I've just uploaded a new release of the Redmine Stuff To Do plugin. This is a bug fix release that should support the released version of Redmine as well as the latest trunk version.
Download
The plugin can be download from the Little Stream Software project or from GitHub.
Changes
You can see more details on the Changelog and Roadmap pages.
What's next
The next release should have a couple of new features. If you have an idea for one, leave a comment here or open a feature request.
Help
If you need help, my Redmine bug tracker is open to the public and you are welcome to ask for help there.
Eric
Tagged: open source redmine redmine plugins
I've just uploaded a new release of the Redmine Question plugin. This is a bug fix release that should support the released version of Redmine as well as the latest trunk version.
Download
The plugin can be download from the Little Stream Software project or from GitHub.
Changes
You can see more details on the Changelog and Roadmap pages.
What's next
The next release should have a couple of new features. If you have an idea for one, leave a comment here or open a feature request.
Help
If you need help, my Redmine bug tracker is open to the public and you are welcome to ask for help there.
Eric
Tagged: open source redmine redmine plugins
I've just uploaded a new release of the Redmine Timesheet plugin. This release has a couple of new features, a few bug fixes, and several translation updates.
Download
The plugin can be download from the Little Stream Software project or from GitHub.
Changes
You can see more details on the Changelog and Roadmap pages.
What's next
Michele Franzin has been working on a fork of the Timesheet plugin that has a really nice calendar view and summary features. Since these didn't make it into 0.5.0, I'd like to pull them into the 0.6.0 release.
Help
If you need help, my Redmine bug tracker is open to the public and you are welcome to ask for help there.
Eric
Tagged: open source redmine redmine plugins
I had a question emailed to me about Redmine and I thought it would make a useful blog post:
If I wanted to add a link example.com to the top menu how would I do that?
I've seen this asked several times and most responses are to modify Redmine's source. While this will work, it will make Redmine upgrades harder. The best solution is to create a small Redmine plugin and drop it into the vendor/plugins directory. Only one Ruby file is needed, plus any language translations.
# init.rb
Redmine::Plugin.register :redmine_static_link do
name 'Redmine link'
author 'Eric Davis of Little Stream Software'
description 'Shows a link on the top menu'
version '0.1.0'
menu :top_menu, :example_link, "http://www.example.com"
end
You can see that all the init.rb does is to register a new plugin and add a :top_menu link to http://www.example.com. Once Redmine is reloaded, you should see the link on the top menu.

I've uploaded the full plugin, along with English language translations. Go ahead and download it and change the link url to what you need.
If you have any other Redmine or Redmine plugin questions that you would like me to write about, please ask them on my User Voice.
Eric
Tagged: open source redmine redmine plugins