Initial Redmine tooling and local plugin forks
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
class ContactsProjectSetting
|
||||
unloadable
|
||||
|
||||
def initialize(project, plugin_name)
|
||||
@project = project
|
||||
@plugin_settings_name = plugin_name
|
||||
Setting["plugin_" + @plugin_settings_name]
|
||||
end
|
||||
|
||||
def method_missing(method_name, *args, &block)
|
||||
return super if /^(.*=)$/ =~ method_name.to_s
|
||||
setting_name = method_name.to_s.gsub(/\?|=/, '')
|
||||
setting_value = if ContactsSetting[@plugin_settings_name + '_' + setting_name, @project].blank?
|
||||
if ContactsSetting.respond_to?(method_name)
|
||||
ContactsSetting.send(method_name)
|
||||
else
|
||||
Setting["plugin_" + @plugin_settings_name][setting_name]
|
||||
end
|
||||
else
|
||||
ContactsSetting[@plugin_settings_name + '_' + setting_name, @project]
|
||||
end
|
||||
|
||||
if /.*\?$/ =~ method_name.to_s
|
||||
setting_value.to_i > 0
|
||||
else
|
||||
setting_value
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,333 @@
|
||||
# encoding: utf-8
|
||||
#
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
module RedmineContacts
|
||||
module Helper
|
||||
def contact_tag_url(tag_name, options = {})
|
||||
{ :controller => 'contacts',
|
||||
:action => 'index',
|
||||
:set_filter => 1,
|
||||
:project_id => @project,
|
||||
:fields => [:tags],
|
||||
:values => { :tags => [tag_name] },
|
||||
:operators => { :tags => '=' } }.merge(options)
|
||||
end
|
||||
|
||||
def skype_to(skype_name, _name = nil)
|
||||
return link_to skype_name, 'skype:' + skype_name + '?call' unless skype_name.blank?
|
||||
end
|
||||
|
||||
def tag_link(tag_name, options = {})
|
||||
style = ContactsSetting.monochrome_tags? ? { :class => 'tag-label' } : { :class => 'tag-label-color', :style => "background-color: #{tag_color(tag_name)}" }
|
||||
tag_count = options.delete(:count)
|
||||
link = link_to tag_name, contact_tag_url(tag_name), options
|
||||
link += content_tag(:span, "(#{tag_count})", :class => 'tag-count') if tag_count
|
||||
content_tag(:span, link, {}.merge(style))
|
||||
end
|
||||
|
||||
def tag_color(tag_name)
|
||||
"##{'%06x' % (tag_name.unpack('H*').first.hex % 0xffffff)}"
|
||||
# "##{"%06x" % (Digest::MD5.hexdigest(tag_name).hex % 0xffffff)}"
|
||||
# "##{"%06x" % (tag_name.hash % 0xffffff).to_s}"
|
||||
end
|
||||
|
||||
def tag_links(tag_list, options = {})
|
||||
content_tag(:span, safe_join(tag_list.map { |tag| tag_link(tag, options) }, ContactsSetting.monochrome_tags? ? ', ' : ' ').html_safe,
|
||||
:class => "tag_list#{' icon icon-tag' if ContactsSetting.monochrome_tags?}") if tag_list
|
||||
end
|
||||
|
||||
def contacts_for_select(project, options = {})
|
||||
scope = Contact.where(options[:where])
|
||||
scope = scope.limit(options[:limit] || 500)
|
||||
scope = scope.companies if options.delete(:is_company)
|
||||
scope = scope.joins(:projects)
|
||||
scope = Rails.version >= '5.1' ? scope.distinct : scope.uniq
|
||||
scope = scope.where(Contact.visible_condition(User.current))
|
||||
scope = scope.by_project(project) if project
|
||||
scope.to_a.sort! { |x, y| x.name <=> y.name }.collect { |m| [options[:short_label] ? m.name : m.name_with_company, m.id.to_s] }
|
||||
end
|
||||
|
||||
def link_to_remote_list_update(text, url_params)
|
||||
link_to_remote(text, { :url => url_params, :method => :get, :update => 'contact_list', :complete => 'window.scrollTo(0,0)' },
|
||||
{ :href => url_for(:params => url_params) }
|
||||
)
|
||||
end
|
||||
|
||||
def contacts_check_box_tags(name, contacts)
|
||||
s = ''
|
||||
contacts.each do |contact|
|
||||
s << "<label>#{ check_box_tag name, contact.id, false, :id => nil } #{contact_tag(contact, :no_link => true)}#{' (' + contact.company + ')' unless contact.company.blank? || contact.is_company? }</label>\n"
|
||||
end
|
||||
s.html_safe
|
||||
end
|
||||
|
||||
def note_source_url(note_source, options = {})
|
||||
polymorphic_path(note_source, options.merge(:project_id => @project))
|
||||
# return {:controller => note_source.class.name.pluralize.downcase, :action => 'show', :project_id => @project, :id => note_source.id }
|
||||
end
|
||||
|
||||
def link_to_source(note_source, options = {})
|
||||
link_to note_source.name, note_source_url(note_source, options)
|
||||
end
|
||||
|
||||
def countries_options_for_select(selected = nil)
|
||||
default_country = l(:label_crm_countries)[ContactsSetting.default_country.to_s.upcase.to_sym] if ContactsSetting.default_country
|
||||
countries = countries_for_select
|
||||
countries = [[default_country, ContactsSetting.default_country.to_s.upcase], ['---', '']] | countries if default_country
|
||||
options_for_select(countries, :disabled => '', :selected => selected)
|
||||
end
|
||||
|
||||
def countries_for_select
|
||||
l(:label_crm_countries).map { |k, v| [v, k.to_s] }.sort
|
||||
end
|
||||
|
||||
def select_contact_tag(name, contact, options={})
|
||||
cross_project_contacts = ContactsSetting.cross_project_contacts? || !!options.delete(:cross_project_contacts)
|
||||
field_id = sanitize_to_id(name)
|
||||
include_blank = !!options[:include_blank]
|
||||
is_company = !!options[:is_company]
|
||||
add_contact = !!options[:add_contact]
|
||||
|
||||
s = ''
|
||||
s << select_tag(name, options_for_select([[contact.try(:name_with_company), contact.try(:id)]], contact.try(:id)), :include_blank => true)
|
||||
s << javascript_tag("$('##{field_id}').select2({
|
||||
ajax: {
|
||||
url: '#{auto_complete_contacts_path(:project_id => (cross_project_contacts ? nil : @project), :is_company => (options[:is_company] ? '1' : nil))}',
|
||||
dataType: 'json',
|
||||
delay: 250,
|
||||
data: function (params) {
|
||||
return { q: params.term };
|
||||
},
|
||||
processResults: function (data, params) {
|
||||
return { results: data };
|
||||
},
|
||||
cache: true
|
||||
},
|
||||
placeholder: ' ',
|
||||
allowClear: #{include_blank},
|
||||
minimumInputLength: 0,
|
||||
width: '60%',
|
||||
templateResult: formatState
|
||||
}).on('select2:open', function (e) {
|
||||
$('.select2-search__field').val(' ').trigger($.Event('input', { which: 13 })).val('');
|
||||
});
|
||||
function formatState (opt) {
|
||||
var $opt = $('<span>' + opt.avatar + ' ' + opt.text + '</span>');
|
||||
return $opt;
|
||||
};")
|
||||
|
||||
if add_contact
|
||||
s << link_to(image_tag('add.png', :style => 'vertical-align: middle; margin-left: 5px;'),
|
||||
new_project_contact_path(@project, :contact_field_name => name, :contacts_is_company => is_company),
|
||||
:remote => true,
|
||||
:method => 'get',
|
||||
:title => l(:label_crm_contact_new),
|
||||
:id => "#{field_id}_add_link",
|
||||
:tabindex => 200) if authorize_for('contacts', 'new')
|
||||
s << javascript_include_tag('attachments')
|
||||
end
|
||||
|
||||
s.html_safe
|
||||
end
|
||||
|
||||
# TODO: Need to add tests for this method (avatar_to).
|
||||
def avatar_to(obj, options = {})
|
||||
# "https://avt.appsmail.ru/mail/sin23matvey/_avatar"
|
||||
|
||||
options[:size] ||= '64'
|
||||
if ActiveRecord::VERSION::MAJOR >= 4
|
||||
unless options[:size].to_s.include?('x')
|
||||
options[:size] = "#{options[:size]}x#{options[:size]}"
|
||||
end
|
||||
else
|
||||
options[:width] ||= options[:size]
|
||||
options[:height] ||= options[:size]
|
||||
end
|
||||
|
||||
options[:class] = 'gravatar'
|
||||
|
||||
obj_icon = obj.is_a?(Contact) ? (obj.is_company ? 'company.png' : 'person.png') : (obj.is_a?(Deal) ? 'deal.png' : 'unknown.png')
|
||||
|
||||
return image_tag(obj_icon, options.merge(:plugin => 'redmine_contacts')) if ENV['NO_AVATAR']
|
||||
|
||||
if obj.is_a?(Deal)
|
||||
if obj.contact
|
||||
avatar_to(obj.contact, options)
|
||||
else
|
||||
image_tag(obj_icon, options.merge(:plugin => 'redmine_contacts'))
|
||||
end
|
||||
elsif obj.is_a?(Contact) && (avatar = obj.avatar) && avatar.readable?
|
||||
avatar_url = url_for :controller => 'attachments', :action => 'contacts_thumbnail', :id => avatar, :size => options[:size]
|
||||
if options[:full_size]
|
||||
link_to(image_tag(avatar_url, options), :controller => 'attachments', :action => 'show', :id => avatar, :filename => avatar.filename)
|
||||
else
|
||||
image_tag(avatar_url, options)
|
||||
end
|
||||
elsif obj.respond_to?(:facebook) && !obj.facebook.blank?
|
||||
image_tag("https://graph.facebook.com/#{obj.facebook.gsub('.*facebook.com\/', '')}/picture?type=square#{'&return_ssl_resources=1' if (request && request.ssl?)}", options)
|
||||
elsif Setting.gravatar_enabled? && obj.is_a?(Contact) && obj.primary_email
|
||||
# options.merge!({:ssl => (request && request.ssl?), :default => "#{request.protocol}#{request.host_with_port}/plugin_assets/redmine_contacts/images/#{obj_icon}"})
|
||||
# gravatar(obj.primary_email.downcase, options) rescue image_tag(obj_icon, options.merge({:plugin => "redmine_contacts"}))
|
||||
avatar("<#{obj.primary_email}>", options)
|
||||
else
|
||||
image_tag(obj_icon, options.merge(:plugin => 'redmine_contacts'))
|
||||
end
|
||||
end
|
||||
|
||||
def contact_tag(contact, options={})
|
||||
avatar_size = options.delete(:size) || 16
|
||||
if contact.visible? && !options[:no_link]
|
||||
contact_avatar = link_to(avatar_to(contact, :size => avatar_size), contact_path(contact, :project_id => @project), :id => "avatar")
|
||||
contact_name = link_to_source(contact, :project_id => @project)
|
||||
else
|
||||
contact_avatar = avatar_to(contact, :size => avatar_size)
|
||||
contact_name = contact.name
|
||||
end
|
||||
|
||||
case options.delete(:type).to_s
|
||||
when 'avatar'
|
||||
contact_avatar.html_safe
|
||||
when 'plain'
|
||||
contact_name.html_safe
|
||||
else
|
||||
content_tag(:span, "#{contact_avatar} #{contact_name}".html_safe, :class => 'contact')
|
||||
end
|
||||
end
|
||||
|
||||
def render_contact_tooltip(contact, options = {})
|
||||
@cached_label_crm_company ||= l(:field_contact_company)
|
||||
@cached_label_job_title = contact.is_company ? l(:field_company_field) : l(:field_contact_job_title)
|
||||
@cached_label_phone ||= l(:field_contact_phone)
|
||||
@cached_label_email ||= l(:field_contact_email)
|
||||
|
||||
emails = contact.emails.any? ? contact.emails.map { |email| "<span class=\"email\" style=\"white-space: nowrap;\">#{mail_to email}</span>" }.join(', ') : ''
|
||||
phones = contact.phones.any? ? contact.phones.map { |phone| "<span class=\"phone\" style=\"white-space: nowrap;\">#{phone}</span>" }.join(', ') : ''
|
||||
|
||||
s = link_to_contact(contact, options) + '<br /><br />'.html_safe
|
||||
s << "<strong>#{@cached_label_job_title}</strong>: #{contact.job_title}<br />".html_safe unless contact.job_title.blank?
|
||||
s << "<strong>#{@cached_label_crm_company}</strong>: #{link_to(contact.contact_company.name, { :controller => 'contacts', :action => 'show', :id => contact.contact_company.id })}<br />".html_safe if !contact.contact_company.blank? && !contact.is_company
|
||||
s << "<strong>#{@cached_label_email}</strong>: #{emails}<br />".html_safe if contact.emails.any?
|
||||
s << "<strong>#{@cached_label_phone}</strong>: #{phones}<br />".html_safe if contact.phones.any?
|
||||
s
|
||||
end
|
||||
|
||||
def link_to_contact(contact, options = {})
|
||||
s = ''
|
||||
html_options = {}
|
||||
html_options = { :class => 'icon icon-vcard' } if options[:icon] == true
|
||||
s << avatar_to(contact, :size => '16') if options[:avatar] == true
|
||||
s << link_to_source(contact, html_options)
|
||||
|
||||
s << "(#{contact.job_title}) " if (options[:job_title] == true) && !contact.job_title.blank?
|
||||
s << " #{l(:label_crm_at_company)} " if (options[:job_title] == true) && !(contact.job_title.blank? || contact.company.blank?)
|
||||
if (options[:company] == true) && contact.contact_company
|
||||
s << link_to(contact.contact_company.name, { :controller => 'contacts', :action => 'show', :id => contact.contact_company.id })
|
||||
else
|
||||
h contact.company
|
||||
end
|
||||
s << "(#{l(:field_contact_tag_names)}: #{contact.tag_list.join(', ')}) " if (options[:tag_list] == true) && !contact.tag_list.blank?
|
||||
s.html_safe
|
||||
end
|
||||
|
||||
def tagsedit_with_source_for(field_id, url)
|
||||
s = ''
|
||||
unless @heads_for_tagsedit_included
|
||||
s << javascript_include_tag(:"tag-it", :plugin => 'redmine_contacts')
|
||||
s << stylesheet_link_tag(:"jquery.tagit.css", :plugin => 'redmine_contacts')
|
||||
@heads_for_tagsedit_included = true
|
||||
end
|
||||
s << javascript_tag("$('#{field_id}').tagit({
|
||||
tagSource: function(search, showChoices) {
|
||||
var that = this;
|
||||
$.ajax({
|
||||
url: '#{url}',
|
||||
data: {q: search.term},
|
||||
success: function(choices) {
|
||||
showChoices(that._subtractArray(jQuery.parseJSON(choices), that.assignedTags()));
|
||||
}
|
||||
});
|
||||
},
|
||||
allowSpaces: true,
|
||||
placeholderText: '#{l(:label_crm_add_tag)}',
|
||||
caseSensitive: false,
|
||||
removeConfirmation: true
|
||||
});")
|
||||
s.html_safe
|
||||
end
|
||||
|
||||
def tagsedit_for(field_id, available_tags='')
|
||||
s = ''
|
||||
unless @heads_for_tagsedit_included
|
||||
s << javascript_include_tag(:"tag-it", :plugin => 'redmine_contacts')
|
||||
s << stylesheet_link_tag(:"jquery.tagit.css", :plugin => 'redmine_contacts')
|
||||
@heads_for_tagsedit_included = true
|
||||
end
|
||||
|
||||
s << javascript_tag("$('#{field_id}').tagit({
|
||||
availableTags: ['#{available_tags}'],
|
||||
allowSpaces: true,
|
||||
placeholderText: '#{l(:label_crm_add_tag)}',
|
||||
caseSensitive: false,
|
||||
removeConfirmation: true
|
||||
});")
|
||||
s.html_safe
|
||||
end
|
||||
|
||||
def note_type_icon(note)
|
||||
note_type_tag = ''
|
||||
case note.type_id
|
||||
when 0
|
||||
note_type_tag = content_tag('span', '', :class => 'icon icon-email', :title => l(:label_crm_note_type_email))
|
||||
when 1
|
||||
note_type_tag = content_tag('span', '', :class => 'icon icon-call', :title => l(:label_crm_note_type_call))
|
||||
when 2
|
||||
note_type_tag = content_tag('span', '', :class => 'icon icon-meeting', :title => l(:label_crm_note_type_meeting))
|
||||
end
|
||||
context = { :type_tag => note_type_tag, :type_id => note.type_id }
|
||||
call_hook(:helper_notes_note_type_tag, context)
|
||||
context[:type_tag].html_safe
|
||||
end
|
||||
def deal_tag(deal, options = {})
|
||||
return deal.name unless deal.visible?
|
||||
deal_name = options[:no_contact] ? deal.name : deal.full_name
|
||||
s = ''
|
||||
s << avatar_to(deal, :size => options.delete(:size) || 16) unless options[:plain]
|
||||
s << ' ' + link_to(deal_name, deal_path(deal))
|
||||
s << " (#{deal.price_to_s}) " unless deal.price.blank? || options[:no_price]
|
||||
s << (options[:plain] ? deal.status.name : deal_status_tag(deal.status)) if deal.status
|
||||
s.html_safe
|
||||
end
|
||||
|
||||
def deal_status_tag(deal_status)
|
||||
status_tag = content_tag(:span, deal_status.name)
|
||||
content_tag(:span, status_tag, :class => 'tag-label-color', :style => "background-color:#{deal_status.color_name};color:white;")
|
||||
end
|
||||
|
||||
def deals_for_select(project, options = {})
|
||||
scope = Deal.visible.where(options[:where]).limit(options[:limit] || 500)
|
||||
scope = scope.by_project(project) if project
|
||||
scope.order("#{Deal.table_name}.name")
|
||||
.collect { |m| [m.name + (options[:short_label] || m.info.blank? ? '' : " - #{m.info}"), m.id.to_s] }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ActionView::Base.send :include, RedmineContacts::Helper
|
||||
@@ -0,0 +1,91 @@
|
||||
# encoding: utf-8
|
||||
#
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
module RedmineContacts
|
||||
module Helpers
|
||||
|
||||
class CrmCalendar
|
||||
include Redmine::I18n
|
||||
attr_reader :startdt, :enddt
|
||||
|
||||
def initialize(date, options = {})
|
||||
@date = date
|
||||
@events = []
|
||||
@ending_events_by_days = {}
|
||||
@starting_events_by_days = {}
|
||||
@start_date_field = options[:start_date_field] || "start_date"
|
||||
@due_date_field = options[:due_date_field] || "due_date"
|
||||
set_language_if_valid options[:language] || current_language
|
||||
period = options[:period] || :month
|
||||
case period
|
||||
when :month
|
||||
@startdt = Date.civil(date.year, date.month, 1)
|
||||
@enddt = (@startdt >> 1)-1
|
||||
# starts from the first day of the week
|
||||
@startdt = @startdt - (@startdt.cwday - first_wday)%7
|
||||
# ends on the last day of the week
|
||||
@enddt = @enddt + (last_wday - @enddt.cwday)%7
|
||||
when :week
|
||||
@startdt = date - (date.cwday - first_wday)%7
|
||||
@enddt = date + (last_wday - date.cwday)%7
|
||||
else
|
||||
raise 'Invalid period'
|
||||
end
|
||||
end
|
||||
|
||||
# Sets calendar events
|
||||
def events=(events)
|
||||
@events = events
|
||||
@ending_events_by_days = @events.group_by {|event| event.send(@start_date_field).to_date if event.send(@start_date_field)}
|
||||
@starting_events_by_days = @events.group_by {|event| event.send(@due_date_field).to_date if event.send(@due_date_field)}
|
||||
end
|
||||
|
||||
# Returns events for the given day
|
||||
def events_on(day)
|
||||
((@ending_events_by_days[day] || []) + (@starting_events_by_days[day] || [])).uniq
|
||||
end
|
||||
|
||||
# Calendar current month
|
||||
def month
|
||||
@date.month
|
||||
end
|
||||
|
||||
# Return the first day of week
|
||||
# 1 = Monday ... 7 = Sunday
|
||||
def first_wday
|
||||
case Setting.start_of_week.to_i
|
||||
when 1
|
||||
@first_dow ||= (1 - 1)%7 + 1
|
||||
when 6
|
||||
@first_dow ||= (6 - 1)%7 + 1
|
||||
when 7
|
||||
@first_dow ||= (7 - 1)%7 + 1
|
||||
else
|
||||
@first_dow ||= (l(:general_first_day_of_week).to_i - 1)%7 + 1
|
||||
end
|
||||
end
|
||||
|
||||
def last_wday
|
||||
@last_dow ||= (first_wday + 5)%7 + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,91 @@
|
||||
# encoding: utf-8
|
||||
#
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
module RedmineContacts
|
||||
module MoneyHelper
|
||||
|
||||
def object_price(obj, price_field = :price)
|
||||
price_to_currency(obj.try(price_field), obj.currency, :symbol => true).to_s if obj.respond_to?(:currency)
|
||||
end
|
||||
|
||||
def prices_collection_by_currency(prices_collection, options={})
|
||||
return [] if prices_collection.blank? || prices_collection == 0
|
||||
prices = prices_collection
|
||||
prices.reject!{|k, v| v.to_i == 0} if options[:hide_zeros]
|
||||
prices.collect{|k, v| content_tag(:span, price_to_currency(v, k, :symbol => true), :style => "white-space: nowrap;")}.compact
|
||||
end
|
||||
|
||||
def deal_currency_icon(currency)
|
||||
case currency.to_s.upcase
|
||||
when 'EUR'
|
||||
"icon-money-euro"
|
||||
when 'GBP'
|
||||
"icon-money-pound"
|
||||
when 'JPY'
|
||||
"icon-money-yen"
|
||||
else
|
||||
"icon-money-dollar"
|
||||
end
|
||||
end
|
||||
|
||||
def collection_for_currencies_select(default_currency = ContactsSetting.default_currency)
|
||||
major_currencies_collection(default_currency)
|
||||
end
|
||||
|
||||
def major_currencies_collection(default_currency)
|
||||
currencies = []
|
||||
currencies << default_currency.to_s unless default_currency.blank?
|
||||
currencies |= ContactsSetting.major_currencies
|
||||
currencies.map do |c|
|
||||
currency = RedmineCrm::Currency.find(c)
|
||||
["#{currency.iso_code} (#{currency.symbol})", currency.iso_code] if currency
|
||||
end.compact.uniq
|
||||
end
|
||||
|
||||
def all_currencies
|
||||
RedmineCrm::Currency.table.inject([]) do |array, (id, attributes)|
|
||||
array ||= []
|
||||
array << ["#{attributes[:name]}" + (attributes[:symbol].blank? ? "" : " (#{attributes[:symbol]})"), attributes[:iso_code]]
|
||||
array
|
||||
end.sort{|x, y| x[0] <=> y[0]}
|
||||
end
|
||||
|
||||
def price_to_currency(price, currency, options={})
|
||||
return '' if price.blank?
|
||||
options[:decimal_mark] = ContactsSetting.decimal_separator unless options[:decimal_mark]
|
||||
options[:thousands_separator] = ContactsSetting.thousands_delimiter unless options[:thousands_separator]
|
||||
# RedmineCrm::Currency.from_float(price.to_f, currency).format(options) rescue ActionController::Base.helpers.number_with_delimiter(price.to_f, :separator => ContactsSetting.decimal_separator, :delimiter => ContactsSetting.thousands_delimiter, :precision => 2)
|
||||
if currency
|
||||
if currency.is_a? String
|
||||
currency = RedmineCrm::Currency.find(currency)
|
||||
end
|
||||
else
|
||||
currency = RedmineCrm::Currency.find("USD")
|
||||
end
|
||||
ActionController::Base.helpers.number_to_currency(price.to_f, :unit => currency.code)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
unless ActionView::Base.included_modules.include?(RedmineContacts::MoneyHelper)
|
||||
ActionView::Base.send(:include, RedmineContacts::MoneyHelper)
|
||||
end
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
module RedmineContacts
|
||||
module Hooks
|
||||
class ControllersTimeEntryReportsHook < Redmine::Hook::ViewListener
|
||||
def controller_timelog_available_criterias(context = {})
|
||||
context[:available_criterias]['contacts'] = { :sql => 'contacts_issues.contact_id',
|
||||
:klass => Contact,
|
||||
:label => :label_crm_contact }
|
||||
end
|
||||
|
||||
def controller_timelog_time_report_joins(context = {})
|
||||
context[:sql] << " LEFT JOIN contacts_issues ON contacts_issues.issue_id = #{Issue.table_name}.id"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,27 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
module RedmineContacts
|
||||
module Hooks
|
||||
class ViewsCustomFieldsHook < Redmine::Hook::ViewListener
|
||||
render_on :view_custom_fields_form_deal_custom_field, :partial => "deals/custom_field_form"
|
||||
render_on :view_custom_fields_form_contact_custom_field, :partial => "contacts/custom_field_form"
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,28 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
module RedmineContacts
|
||||
module Hooks
|
||||
class ViewsIssuesHook < Redmine::Hook::ViewListener
|
||||
render_on :view_issues_sidebar_planning_bottom, :partial => "contacts_issues/contacts", :locals => {:contact_issue => @issue}
|
||||
render_on :view_issues_form_details_bottom, :partial => 'deals_issues/form'
|
||||
render_on :view_issues_show_details_bottom, :partial => 'deals_issues/show'
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,27 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
module RedmineContacts
|
||||
module Hooks
|
||||
class ViewsLayoutsHook < Redmine::Hook::ViewListener
|
||||
render_on :view_layouts_base_body_bottom, :partial => 'common/contacts_select2_data'
|
||||
render_on :view_layouts_base_html_head, :partial => 'contacts_issues/additional_assets'
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,26 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
module RedmineContacts
|
||||
module Hooks
|
||||
class ViewsUsersHook < Redmine::Hook::ViewListener
|
||||
render_on :view_projects_show_left, :partial => "projects/contacts"
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,28 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# include ContactsHelper
|
||||
|
||||
module RedmineContacts
|
||||
module Hooks
|
||||
class ViewsUsersHook < Redmine::Hook::ViewListener
|
||||
render_on :view_account_left_bottom, :partial => "users/contact", :locals => {:user => @user}
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,64 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
class AddressesDrop < Liquid::Drop
|
||||
|
||||
def initialize(addresses)
|
||||
@addresses = addresses
|
||||
end
|
||||
|
||||
def before_method(id)
|
||||
address = @addresses.where(:id => id).first || Address.new
|
||||
AddressDrop.new address
|
||||
end
|
||||
|
||||
def all
|
||||
@all ||= @addresses.map do |address|
|
||||
AddressDrop.new address
|
||||
end
|
||||
end
|
||||
|
||||
def visible
|
||||
@visible ||= @addresses.visible.map do |address|
|
||||
AddressDrop.new address
|
||||
end
|
||||
end
|
||||
|
||||
def each(&block)
|
||||
all.each(&block)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
class AddressDrop < Liquid::Drop
|
||||
|
||||
delegate :id, :address_type, :street1, :street2, :city, :region, :postcode, :country_code, :country, :full_address, :post_address, :to => :@address
|
||||
|
||||
def initialize(address)
|
||||
@address = address
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def helpers
|
||||
Rails.application.routes.url_helpers
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,91 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
class ContactsDrop < Liquid::Drop
|
||||
|
||||
def initialize(contacts)
|
||||
@contacts = contacts
|
||||
end
|
||||
|
||||
def before_method(id)
|
||||
contact = @contacts.where(:id => id).first || Contact.new
|
||||
ContactDrop.new contact
|
||||
end
|
||||
|
||||
def all
|
||||
@all ||= @contacts.map do |contact|
|
||||
ContactDrop.new contact
|
||||
end
|
||||
end
|
||||
|
||||
def visible
|
||||
@visible ||= @contacts.visible.map do |contact|
|
||||
ContactDrop.new contact
|
||||
end
|
||||
end
|
||||
|
||||
def each(&block)
|
||||
all.each(&block)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
class ContactDrop < Liquid::Drop
|
||||
|
||||
delegate :id, :name, :first_name, :last_name, :middle_name, :company, :phones, :emails, :primary_email, :website, :skype_name, :birthday, :age, :background, :job_title, :is_company, :tag_list, :post_address, :to => :@contact
|
||||
|
||||
def initialize(contact)
|
||||
@contact = contact
|
||||
end
|
||||
|
||||
def contact_company
|
||||
ContactDrop.new @contact.contact_company if @contact.contact_company
|
||||
end
|
||||
|
||||
def company_contacts
|
||||
@contact.company_contacts.map{|c| ContactDrop.new c } if @contact.company_contacts
|
||||
end
|
||||
|
||||
def avatar_diskfile
|
||||
@contact.avatar.diskfile
|
||||
end
|
||||
|
||||
def avatar_url
|
||||
helpers.url_for :controller => "attachments", :action => "contacts_thumbnail", :id => @contact.avatar, :size => '64', :only_path => true
|
||||
end
|
||||
|
||||
def notes
|
||||
@contact.notes.map{|n| NoteDrop.new(n) }
|
||||
end
|
||||
|
||||
def address
|
||||
AddressDrop.new(@contact.address) if @contact.address
|
||||
end
|
||||
def custom_field_values
|
||||
@contact.custom_field_values
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def helpers
|
||||
Rails.application.routes.url_helpers
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,77 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
class DealsDrop < Liquid::Drop
|
||||
|
||||
def initialize(deals)
|
||||
@deals = deals
|
||||
end
|
||||
|
||||
def before_method(id)
|
||||
deal = @deals.where(:id => id).first || Deal.new
|
||||
DealDrop.new deal
|
||||
end
|
||||
|
||||
def all
|
||||
@all ||= @deals.map do |deal|
|
||||
DealDrop.new deal
|
||||
end
|
||||
end
|
||||
|
||||
def visible
|
||||
@visible ||= @deals.visible.map do |deal|
|
||||
DealDrop.new deal
|
||||
end
|
||||
end
|
||||
|
||||
def each(&block)
|
||||
all.each(&block)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
class DealDrop < Liquid::Drop
|
||||
|
||||
delegate :id, :name, :created_on, :due_date, :price, :price_type, :currency, :background, :probability, :to => :@deal
|
||||
|
||||
def initialize(deal)
|
||||
@deal = deal
|
||||
end
|
||||
|
||||
def notes
|
||||
@deal.notes.map{|n| NoteDrop.new(n) }
|
||||
end
|
||||
|
||||
def category
|
||||
@deal.category.name if @deal.category
|
||||
end
|
||||
|
||||
def contact
|
||||
ContactDrop.new @deal.contact if @deal.contact
|
||||
end
|
||||
|
||||
def status
|
||||
@deal.status.name if @deal.status
|
||||
end
|
||||
|
||||
def custom_field_values
|
||||
@deal.custom_field_values
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,61 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
class NotesDrop < Liquid::Drop
|
||||
|
||||
def initialize(notes)
|
||||
@notes = notes
|
||||
end
|
||||
|
||||
def before_method(id)
|
||||
note = @notes.where(:id => id).first || Note.new
|
||||
NoteDrop.new note
|
||||
end
|
||||
|
||||
def all
|
||||
@all ||= @notes.map do |note|
|
||||
NoteDrop.new note
|
||||
end
|
||||
end
|
||||
|
||||
def visible
|
||||
@visible ||= @notes.visible.map do |note|
|
||||
NoteDrop.new note
|
||||
end
|
||||
end
|
||||
|
||||
def each(&block)
|
||||
all.each(&block)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
class NoteDrop < Liquid::Drop
|
||||
|
||||
delegate :id, :subject, :content, :type_id, :to => :@note
|
||||
|
||||
def initialize(note)
|
||||
@note = note
|
||||
end
|
||||
def custom_field_values
|
||||
@note.custom_field_values
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,97 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
require "redmine_contacts/liquid/drops/contacts_drop"
|
||||
require "redmine_contacts/liquid/drops/deals_drop"
|
||||
require "redmine_contacts/liquid/drops/notes_drop"
|
||||
require "redmine_contacts/liquid/drops/addresses_drop"
|
||||
|
||||
module RedmineContacts
|
||||
module Liquid
|
||||
module Filters
|
||||
include RedmineCrm::MoneyHelper
|
||||
|
||||
def underscore(input)
|
||||
input.to_s.gsub(' ', '_').gsub('/', '_').underscore
|
||||
end
|
||||
|
||||
def dasherize(input)
|
||||
input.to_s.gsub(' ', '-').gsub('/', '-').dasherize
|
||||
end
|
||||
|
||||
def encode(input)
|
||||
Rack::Utils.escape(input)
|
||||
end
|
||||
|
||||
# alias newline_to_br
|
||||
def multi_line(input)
|
||||
input.to_s.gsub("\n", '<br/>').html_safe
|
||||
end
|
||||
|
||||
def concat(input, *args)
|
||||
result = input.to_s
|
||||
args.flatten.each { |a| result << a.to_s }
|
||||
result
|
||||
end
|
||||
|
||||
# right justify and padd a string
|
||||
def rjust(input, integer, padstr = '')
|
||||
input.to_s.rjust(integer, padstr)
|
||||
end
|
||||
|
||||
# left justify and padd a string
|
||||
def ljust(input, integer, padstr = '')
|
||||
input.to_s.ljust(integer, padstr)
|
||||
end
|
||||
|
||||
def textile(input)
|
||||
::RedCloth3.new(input).to_html
|
||||
end
|
||||
|
||||
def currency(input, currency_code=nil)
|
||||
price_to_currency(input, currency_code || container_currency, :converted => false)
|
||||
end
|
||||
|
||||
def custom_field(input, field_name)
|
||||
if input.respond_to?(:custom_field_values)
|
||||
input.custom_field_values.detect{|cfv| cfv.custom_field.name == field_name}.try(:value)
|
||||
end
|
||||
end
|
||||
|
||||
def attachment(input, file_name)
|
||||
if input.respond_to?(:attachments)
|
||||
input.attachments.detect{|a| a.file_name == file_name}.try(:diskfile)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def container
|
||||
@container ||= @context.registers[:container]
|
||||
end
|
||||
|
||||
def container_currency
|
||||
container.currency if container.respond_to?(:currency)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
::Liquid::Template.register_filter(RedmineContacts::Liquid::Filters)
|
||||
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,51 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
module RedmineContacts
|
||||
module Patches
|
||||
module ActionControllerPatch
|
||||
def self.included(base)
|
||||
base.extend(ClassMethods) if Rails::VERSION::MAJOR < 4
|
||||
|
||||
base.class_eval do
|
||||
end
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
if Rails::VERSION::MAJOR < 4
|
||||
def before_action(*filters, &block)
|
||||
before_filter(*filters, &block)
|
||||
end
|
||||
|
||||
def after_action(*filters, &block)
|
||||
after_filter(*filters, &block)
|
||||
end
|
||||
|
||||
def skip_before_action(*filters)
|
||||
skip_before_filter(*filters)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
unless ActionController::Base.included_modules.include?(RedmineContacts::Patches::ActionControllerPatch)
|
||||
ActionController::Base.send(:include, RedmineContacts::Patches::ActionControllerPatch)
|
||||
end
|
||||
@@ -0,0 +1,44 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
module RedmineContacts
|
||||
module Patches
|
||||
module ApplicationControllerPatch
|
||||
def self.included(base)
|
||||
base.send(:include, InstanceMethods)
|
||||
|
||||
base.class_eval do
|
||||
alias_method :user_setup_without_contacts, :user_setup
|
||||
alias_method :user_setup, :user_setup_with_contacts
|
||||
end
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
def user_setup_with_contacts
|
||||
user_setup_without_contacts
|
||||
ContactsSetting.check_cache
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
unless ApplicationController.included_modules.include?(RedmineContacts::Patches::ApplicationControllerPatch)
|
||||
ApplicationController.send(:include, RedmineContacts::Patches::ApplicationControllerPatch)
|
||||
end
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
require_dependency 'attachments_controller'
|
||||
require_dependency 'attachment'
|
||||
|
||||
module RedmineContacts
|
||||
module Patches
|
||||
|
||||
module AttachmentsControllerPatch
|
||||
def self.included(base)
|
||||
base.send(:include, InstanceMethods)
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
|
||||
def contacts_thumbnail
|
||||
find_attachment
|
||||
size = params[:size].to_i
|
||||
size = 64 unless size > 0
|
||||
if @attachment.readable? && @attachment.thumbnailable?
|
||||
if Redmine::Thumbnail.convert_available?
|
||||
target = File.join(@attachment.class.thumbnails_storage_path, "#{@attachment.id}_#{@attachment.digest}_#{size}.thumb")
|
||||
thumbnail = RedmineContacts::Thumbnail.generate(@attachment.diskfile, target, size)
|
||||
else
|
||||
thumbnail = @attachment.diskfile
|
||||
end
|
||||
if stale?(:etag => @attachment.digest)
|
||||
send_file thumbnail, :filename => (request.env['HTTP_USER_AGENT'] =~ %r{MSIE} ? ERB::Util.url_encode(@attachment.filename) : @attachment.filename),
|
||||
:type => detect_content_type(@attachment),
|
||||
:disposition => 'inline'
|
||||
end
|
||||
else
|
||||
# No thumbnail for the attachment or thumbnail could not be created
|
||||
render :nothing => true, :status => 404
|
||||
end
|
||||
rescue => e
|
||||
logger.error "An error occured while generating contact thumbnail for #{@attachment.disk_filename} to #{target}\nException was: #{e.message}" if logger
|
||||
return nil
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_attachment
|
||||
@attachment = Attachment.find(params[:id])
|
||||
# Show 404 if the filename in the url is wrong
|
||||
raise ActiveRecord::RecordNotFound if params[:filename] && params[:filename] != @attachment.filename
|
||||
@project = @attachment.project
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
module AttachmentPatch
|
||||
|
||||
module InstanceMethods
|
||||
|
||||
def is_contacts_thumbnailable?
|
||||
(self.is_pdf? && self.filesize < 600.kilobytes) || self.image?
|
||||
end
|
||||
|
||||
def is_pdf?
|
||||
self.filename =~ /\.(pdf)$/i
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def self.included(base) # :nodoc:
|
||||
base.send :include, InstanceMethods
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
unless Attachment.included_modules.include?(RedmineContacts::Patches::AttachmentPatch)
|
||||
Attachment.send(:include, RedmineContacts::Patches::AttachmentPatch)
|
||||
end
|
||||
|
||||
unless AttachmentsController.included_modules.include?(RedmineContacts::Patches::AttachmentsControllerPatch)
|
||||
AttachmentsController.send(:include, RedmineContacts::Patches::AttachmentsControllerPatch)
|
||||
end
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
require_dependency 'auto_completes_controller'
|
||||
|
||||
module RedmineContacts
|
||||
module Patches
|
||||
module AutoCompletesControllerPatch
|
||||
def self.included(base)
|
||||
base.send(:include, InstanceMethods)
|
||||
|
||||
base.class_eval do
|
||||
end
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
def deals
|
||||
@deals = []
|
||||
q = (params[:q] || params[:term]).to_s.strip
|
||||
scope = Deal.joins(:project).where({})
|
||||
scope = scope.limit(params[:limit] || 10)
|
||||
scope = scope.by_project(@project) if @project
|
||||
if q.match(/\A#?(\d+)\z/)
|
||||
@deals << scope.visible.find_by_id($1.to_i)
|
||||
end
|
||||
scope = scope.live_search_with_contact(q) unless q.blank?
|
||||
@deals += scope.visible.order("#{Deal.table_name}.name")
|
||||
@deals.uniq! { |deal| deal.id }
|
||||
render :layout => false, :partial => 'deals'
|
||||
end
|
||||
|
||||
def contact_tags
|
||||
@name = params[:q].to_s
|
||||
@tags = Contact.available_tags :name_like => @name, :limit => 10
|
||||
render :layout => false, :partial => 'crm_tag_list'
|
||||
end
|
||||
|
||||
def taggable_tags
|
||||
klass = Object.const_get(params[:taggable_type].camelcase)
|
||||
@name = params[:q].to_s
|
||||
@tags = klass.all_tag_counts(:conditions => ["#{RedmineCrm::Tag.table_name}.name LIKE ?", "%#{@name}%"], :limit => 10)
|
||||
render :layout => false, :partial => 'crm_tag_list'
|
||||
end
|
||||
|
||||
def contacts
|
||||
@contacts = []
|
||||
q = (params[:q] || params[:term]).to_s.strip
|
||||
scope = Contact.includes(:avatar).where({})
|
||||
scope = scope.limit(params[:limit] || 10)
|
||||
scope = scope.companies if params[:is_company]
|
||||
scope = scope.joins(:projects).where(Contact.visible_condition(User.current))
|
||||
scope = Rails.version >= '5.1' ? scope.distinct : scope.uniq
|
||||
q.split(' ').collect { |search_string| scope = scope.live_search(search_string) } unless q.blank?
|
||||
scope = scope.by_project(@project) if @project
|
||||
@contacts = scope.to_a.sort! { |x, y| x.name <=> y.name }
|
||||
render :layout => false, :partial => 'contacts'
|
||||
end
|
||||
|
||||
def companies
|
||||
@companies = []
|
||||
q = (params[:q] || params[:term]).to_s.strip
|
||||
if q.present?
|
||||
scope = Contact.joins(:projects).where({})
|
||||
scope = scope.limit(params[:limit] || 10)
|
||||
scope = scope.includes(:avatar)
|
||||
scope = scope.by_project(@project) if @project
|
||||
scope = scope.where('LOWER(first_name) LIKE LOWER(?)', "#{q}%") unless q.blank?
|
||||
@companies = scope.visible.companies.order("#{Contact.table_name}.first_name")
|
||||
end
|
||||
render :layout => false, :partial => 'companies'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
unless AutoCompletesController.included_modules.include?(RedmineContacts::Patches::AutoCompletesControllerPatch)
|
||||
AutoCompletesController.send(:include, RedmineContacts::Patches::AutoCompletesControllerPatch)
|
||||
end
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
module RedmineContacts
|
||||
module Patches
|
||||
module QueryPatch
|
||||
def self.included(base) # :nodoc:
|
||||
base.send(:include, InstanceMethods)
|
||||
base.class_eval do
|
||||
unloadable
|
||||
class << self
|
||||
VISIBILITY_PRIVATE = 0
|
||||
VISIBILITY_ROLES = 1
|
||||
VISIBILITY_PUBLIC = 2
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
VISIBILITY_PRIVATE = 0
|
||||
VISIBILITY_ROLES = 1
|
||||
VISIBILITY_PUBLIC = 2
|
||||
|
||||
def is_private?
|
||||
visibility == VISIBILITY_PRIVATE
|
||||
end
|
||||
|
||||
def is_public?
|
||||
!is_private?
|
||||
end
|
||||
|
||||
def visibility=(value)
|
||||
self.is_public = value == VISIBILITY_PUBLIC
|
||||
end
|
||||
|
||||
def visibility
|
||||
self.is_public ? VISIBILITY_PUBLIC : VISIBILITY_PRIVATE
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
unless Query.included_modules.include?(RedmineContacts::Patches::QueryPatch)
|
||||
Query.send(:include, RedmineContacts::Patches::QueryPatch)
|
||||
end
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
module RedmineContacts
|
||||
module Patches
|
||||
module ActiveRecordBasePatch
|
||||
def self.included(base)
|
||||
base.send(:include, InstanceMethods)
|
||||
base.class_eval do
|
||||
alias_method :has_many_without_contacts, :has_many
|
||||
alias_method :has_many, :has_many_with_contacts
|
||||
end
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
def has_many_with_contacts(name, param2 = nil, *param3, &extension)
|
||||
return has_many_without_contacts(name, param2, *param3, &extension) if param3 && param3.is_a?(Array) && param3[0] && param3[0][:through]
|
||||
if param2.nil?
|
||||
options = {}
|
||||
else
|
||||
if param2.is_a?(Proc)
|
||||
scope = param2
|
||||
options = param3.empty? ? {} : param3[0]
|
||||
else
|
||||
options = param2
|
||||
end
|
||||
end
|
||||
if ActiveRecord::VERSION::MAJOR >= 4
|
||||
scope, options = build_scope_and_options(options) if scope.nil?
|
||||
has_many_without_contacts(name, scope, options, &extension)
|
||||
else
|
||||
has_many_without_contacts(name, options, &extension)
|
||||
end
|
||||
end
|
||||
|
||||
def build_scope_and_options(options)
|
||||
scope_opts, opts = parse_options(options)
|
||||
|
||||
unless scope_opts.empty?
|
||||
scope = lambda do
|
||||
scope_opts.inject(self) { |result, hash| result.send *hash }
|
||||
end
|
||||
end
|
||||
[defined?(scope) ? scope : nil, opts]
|
||||
end
|
||||
|
||||
def parse_options(opts)
|
||||
scope_opts = {}
|
||||
[:order, :having, :select, :group, :limit, :offset, :readonly].each do |o|
|
||||
scope_opts[o] = opts.delete o if opts[o]
|
||||
end
|
||||
scope_opts[:where] = opts.delete :conditions if opts[:conditions]
|
||||
scope_opts[:joins] = opts.delete :include if opts [:include]
|
||||
scope_opts[:distinct] = opts.delete :uniq if opts[:uniq]
|
||||
|
||||
[scope_opts, opts]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if defined?(ActiveRecord::Base)
|
||||
ActiveRecord::Base.extend RedmineContacts::Patches::ActiveRecordBasePatch::InstanceMethods
|
||||
unless ActiveRecord::Associations::ClassMethods.included_modules.include?(RedmineContacts::Patches::ActiveRecordBasePatch)
|
||||
ActiveRecord::Associations::ClassMethods.send(:include, RedmineContacts::Patches::ActiveRecordBasePatch)
|
||||
end
|
||||
end
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
module RedmineContacts
|
||||
module Patches
|
||||
module ActiveRecordSanitizationPatch
|
||||
def self.included(base)
|
||||
base.class_eval do
|
||||
def quote_value(value, column = nil)
|
||||
connection.quote(value, column)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
unless ActiveRecord::Sanitization::ClassMethods.included_modules.include?(RedmineContacts::Patches::ActiveRecordSanitizationPatch)
|
||||
ActiveRecord::Sanitization::ClassMethods.send(:include, RedmineContacts::Patches::ActiveRecordSanitizationPatch)
|
||||
end
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
module RedmineContacts
|
||||
module Patches
|
||||
module ApplicationHelperPatch
|
||||
def self.included(base) # :nodoc:
|
||||
base.class_eval do
|
||||
unloadable # Send unloadable so it will not be unloaded in development
|
||||
|
||||
def stocked_reorder_link(object, name = nil, url = {}, method = :post)
|
||||
Redmine::VERSION.to_s > '3.3' ? reorder_handle(object, :param => name) : reorder_links(name, url, method)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
unless ApplicationHelper.included_modules.include?(RedmineContacts::Patches::ApplicationHelperPatch)
|
||||
ApplicationHelper.send(:include, RedmineContacts::Patches::ApplicationHelperPatch)
|
||||
end
|
||||
@@ -0,0 +1,50 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
module RedmineContacts
|
||||
module Patches
|
||||
module UserPatch
|
||||
def self.included(base)
|
||||
base.class_eval do
|
||||
scope :having_mail, lambda {|arg|
|
||||
addresses = Array.wrap(arg).map {|a| a.to_s.downcase}
|
||||
if addresses.any?
|
||||
joins(:email_addresses).where("LOWER(#{EmailAddress.table_name}.address) IN (?)", addresses).uniq
|
||||
else
|
||||
none
|
||||
end
|
||||
}
|
||||
|
||||
def self.find_by_mail(mail)
|
||||
if ActiveRecord::VERSION::MAJOR >= 4
|
||||
mail.is_a?(Array) ? mail : [mail]
|
||||
having_mail(mail).first
|
||||
else
|
||||
where("LOWER(mail) = ?", mail.to_s.downcase).first
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
unless User.included_modules.include?(RedmineContacts::Patches::UserPatch)
|
||||
User.send(:include, RedmineContacts::Patches::UserPatch)
|
||||
end
|
||||
@@ -0,0 +1,26 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
if Redmine::VERSION.to_s < '2.4'
|
||||
Dir[File.dirname(__FILE__) + '/compatibility/2.3/*.rb'].each { |f| require f }
|
||||
end
|
||||
|
||||
if ActiveRecord::VERSION::MAJOR > 3
|
||||
Dir[File.dirname(__FILE__) + '/compatibility/rails/*.rb'].each { |f| require f }
|
||||
end
|
||||
@@ -0,0 +1,59 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
require_dependency 'custom_fields_helper'
|
||||
|
||||
module RedmineContacts
|
||||
module Patches
|
||||
module CustomFieldsHelperPatch
|
||||
def self.included(base) # :nodoc:
|
||||
base.send(:include, InstanceMethods)
|
||||
|
||||
base.class_eval do
|
||||
if Rails.version < '5.1'
|
||||
alias_method_chain :custom_fields_tabs, :contacts_tab
|
||||
else
|
||||
alias_method :custom_fields_tabs_without_contacts, :custom_fields_tabs
|
||||
alias_method :custom_fields_tabs, :custom_fields_tabs_with_contacts
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
def custom_fields_tabs_with_contacts_tab
|
||||
new_tabs = []
|
||||
new_tabs << { :name => 'ContactCustomField', :partial => 'custom_fields/index', :label => :label_contact_plural }
|
||||
new_tabs << { :name => 'DealCustomField', :partial => 'custom_fields/index', :label => :label_deal_plural }
|
||||
new_tabs << { :name => 'NoteCustomField', :partial => 'custom_fields/index', :label => :label_crm_note_plural }
|
||||
custom_fields_tabs_without_contacts_tab | new_tabs
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if Redmine::VERSION.to_s > '2.5'
|
||||
CustomFieldsHelper::CUSTOM_FIELDS_TABS << { :name => 'ContactCustomField', :partial => 'custom_fields/index', :label => :label_contact_plural }
|
||||
CustomFieldsHelper::CUSTOM_FIELDS_TABS << { :name => 'DealCustomField', :partial => 'custom_fields/index', :label => :label_deal_plural }
|
||||
CustomFieldsHelper::CUSTOM_FIELDS_TABS << { :name => 'NoteCustomField', :partial => 'custom_fields/index', :label => :label_crm_note_plural }
|
||||
else
|
||||
unless CustomFieldsHelper.included_modules.include?(RedmineContacts::Patches::CustomFieldsHelperPatch)
|
||||
CustomFieldsHelper.send(:include, RedmineContacts::Patches::CustomFieldsHelperPatch)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,54 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
require_dependency 'issue'
|
||||
require_dependency 'contact'
|
||||
|
||||
module RedmineContacts
|
||||
module Patches
|
||||
module IssuePatch
|
||||
def self.included(base) # :nodoc:
|
||||
base.send(:include, InstanceMethods)
|
||||
base.class_eval do
|
||||
unloadable # Send unloadable so it will not be unloaded in development
|
||||
has_and_belongs_to_many :contacts, :uniq => true
|
||||
has_one :deals_issue
|
||||
has_one :deal, :through => :deals_issue
|
||||
accepts_nested_attributes_for :deals_issue, :reject_if => :reject_deal, :allow_destroy => true
|
||||
|
||||
safe_attributes 'deals_issue_attributes',
|
||||
:if => lambda { |issue, user| user.allowed_to?(:edit_deals, issue.project) }
|
||||
end
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
def reject_deal(attributes)
|
||||
exists = attributes['id'].present?
|
||||
empty = attributes[:deal_id].blank?
|
||||
attributes[:_destroy] = 1 if exists && empty
|
||||
!exists && empty
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
unless Issue.included_modules.include?(RedmineContacts::Patches::IssuePatch)
|
||||
Issue.send(:include, RedmineContacts::Patches::IssuePatch)
|
||||
end
|
||||
@@ -0,0 +1,138 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
require_dependency 'query'
|
||||
|
||||
module RedmineContacts
|
||||
module Patches
|
||||
module IssueQueryPatch
|
||||
def self.included(base)
|
||||
base.send(:include, InstanceMethods)
|
||||
base.send(:include, RedmineContacts::Helper)
|
||||
base.class_eval do
|
||||
unloadable
|
||||
|
||||
alias_method :available_columns_without_contacts, :available_columns
|
||||
alias_method :available_columns, :available_columns_with_contacts
|
||||
|
||||
alias_method :initialize_available_filters_without_contacts, :initialize_available_filters
|
||||
alias_method :initialize_available_filters, :initialize_available_filters_with_contacts
|
||||
end
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
def sql_for_contacts_field(_field, operator, value)
|
||||
case operator
|
||||
when '=', '*'
|
||||
compare = 'IN'
|
||||
when '!', '!*'
|
||||
compare = 'NOT IN'
|
||||
end
|
||||
contacts_select = "SELECT contacts_issues.issue_id FROM contacts_issues
|
||||
WHERE contacts_issues.contact_id IN (#{value.join(',')})"
|
||||
issues_with_contacts = 'SELECT DISTINCT(issue_id) FROM contacts_issues'
|
||||
|
||||
"(#{Issue.table_name}.id #{compare} (#{ %w(= !).include?(operator) ? contacts_select : issues_with_contacts }))"
|
||||
end
|
||||
|
||||
def sql_for_companies_field(_field, operator, value)
|
||||
compare = operator == '=' ? 'IN' : 'NOT IN'
|
||||
employes_select = "SELECT contacts_issues.issue_id FROM contacts_issues
|
||||
WHERE contacts_issues.contact_id IN
|
||||
( SELECT c_1.id from #{Contact.table_name}
|
||||
LEFT OUTER JOIN #{Contact.table_name} AS c_1 ON c_1.company = #{Contact.table_name}.first_name
|
||||
WHERE #{Contact.table_name}.id IN (#{value.join(',')})
|
||||
)"
|
||||
companies_select = "SELECT contacts_issues.issue_id FROM contacts_issues
|
||||
WHERE contacts_issues.contact_id IN (#{value.join(',')})"
|
||||
|
||||
"((#{Issue.table_name}.id #{compare} (#{employes_select}))
|
||||
OR (#{Issue.table_name}.id #{compare} (#{companies_select})))"
|
||||
end
|
||||
|
||||
def sql_for_deal_field(_field, operator, value)
|
||||
if operator == '!*'
|
||||
compare = 'NOT IN'
|
||||
operator = '*'
|
||||
else
|
||||
compare = 'IN'
|
||||
end
|
||||
|
||||
deals_select = "SELECT deals_issues.issue_id FROM deals_issues
|
||||
WHERE #{sql_for_field('deal_id', operator, value, 'deals_issues', 'deal_id')}"
|
||||
|
||||
"(#{Issue.table_name}.id #{compare} (#{deals_select}))"
|
||||
end
|
||||
|
||||
def available_columns_with_contacts
|
||||
if @available_columns.blank?
|
||||
@available_columns = available_columns_without_contacts
|
||||
@available_columns << QueryColumn.new(:deal, :caption => :label_deal) if User.current.allowed_to?(:view_deals, project, :global => true)
|
||||
@available_columns << QueryColumn.new(:contacts) if User.current.allowed_to?(:view_contacts, project, :global => true)
|
||||
else
|
||||
available_columns_without_contacts
|
||||
end
|
||||
@available_columns
|
||||
end
|
||||
|
||||
def initialize_available_filters_with_contacts
|
||||
initialize_available_filters_without_contacts
|
||||
|
||||
if !available_filters.key?('contacts') && User.current.allowed_to?(:view_contacts, project, :global => true)
|
||||
selected_contacts = filters['contacts'].blank? ? [] : Contact.visible.where(:id => filters['contacts'][:values]).map { |c| [c.name, c.id.to_s] }
|
||||
add_available_filter('contacts', :type => :list_optional, :field_format => 'contact', :name => l(:field_contacts), :values => selected_contacts)
|
||||
end
|
||||
|
||||
if !available_filters.key?('companies') && User.current.allowed_to?(:view_contacts, project, :global => true)
|
||||
selected_companies = filters['companies'].blank? ? [] : Contact.visible.where(:id => filters['companies'][:values]).map { |c| [c.name, c.id.to_s] }
|
||||
add_available_filter('companies', :type => :list, :field_format => 'company', :name => l(:field_companies), :values => selected_companies)
|
||||
end
|
||||
|
||||
if !available_filters.key?('deal') && User.current.allowed_to?(:view_deals, project, :global => true)
|
||||
selected_deals = filters['deal'].blank? ? [] : Deal.visible.where(:id => filters['deal'][:values]).map { |deal| [deal.name, deal.id.to_s] }
|
||||
add_available_filter('deal', :type => :list_optional, :field_format => 'deal', :name => l(:label_deal), :values => selected_deals)
|
||||
end
|
||||
end
|
||||
|
||||
def contact_query_values(options = {})
|
||||
if options[:field] == 'deal'
|
||||
deals_for_select(nil, :where => { :id => options[:values] }, :short_label => true)
|
||||
else
|
||||
contacts_for_select(nil, :where => { :id => options[:values] }, :short_label => true)
|
||||
end
|
||||
end
|
||||
|
||||
def default_contact_query_values(options = {})
|
||||
records =
|
||||
if options[:field] == 'deal'
|
||||
Deal.visible.where(:id => options[:values])
|
||||
else
|
||||
Contact.joins(:projects).where(Contact.visible_condition(User.current)).where(:id => options[:values])
|
||||
end
|
||||
|
||||
records.to_a.sort! { |x, y| x.name <=> y.name }.collect { |m| [m.name, m.id.to_s] }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
unless IssueQuery.included_modules.include?(RedmineContacts::Patches::IssueQueryPatch)
|
||||
IssueQuery.send(:include, RedmineContacts::Patches::IssueQueryPatch)
|
||||
end
|
||||
@@ -0,0 +1,47 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
module RedmineContacts
|
||||
module Patches
|
||||
module IssuesControllerPatch
|
||||
def self.included(base) # :nodoc:
|
||||
base.send(:include, InstanceMethods)
|
||||
|
||||
base.class_eval do
|
||||
unloadable
|
||||
alias_method :build_new_issue_from_params_without_contacts, :build_new_issue_from_params
|
||||
alias_method :build_new_issue_from_params, :build_new_issue_from_params_with_contacts
|
||||
end
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
def build_new_issue_from_params_with_contacts
|
||||
build_new_issue_from_params_without_contacts
|
||||
return if @issue.blank? || params[:deal_id].blank?
|
||||
deal = Deal.visible.where(:id => params[:deal_id]).first
|
||||
@issue.deals_issue = DealsIssue.new(:issue => @issue, :deal => deal) if deal
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
unless IssuesController.included_modules.include?(RedmineContacts::Patches::IssuesControllerPatch)
|
||||
IssuesController.send(:include, RedmineContacts::Patches::IssuesControllerPatch)
|
||||
end
|
||||
@@ -0,0 +1,41 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
module RedmineContacts
|
||||
module Patches
|
||||
module IssuesHelperPatch
|
||||
def self.included(base) # :nodoc:
|
||||
base.send(:include, InstanceMethods)
|
||||
base.class_eval do
|
||||
unloadable
|
||||
end
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
def render_custom_fields_rows(issue)
|
||||
render_half_width_custom_fields_rows(issue)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
unless IssuesHelper.included_modules.include?(RedmineContacts::Patches::IssuesHelperPatch)
|
||||
IssuesHelper.send(:include, RedmineContacts::Patches::IssuesHelperPatch)
|
||||
end
|
||||
@@ -0,0 +1,115 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
module RedmineContacts
|
||||
module Patches
|
||||
module MailerPatch
|
||||
module ClassMethods
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
def crm_note_add(note)
|
||||
redmine_headers 'Project' => note.source.project.identifier,
|
||||
'X-Notable-Id' => note.source.id,
|
||||
'X-Note-Id' => note.id
|
||||
@author = note.author
|
||||
message_id note
|
||||
recipients = note.source.recipients
|
||||
cc = (note.source.respond_to?(:all_watcher_recepients) ? note.source.all_watcher_recepients : note.source.watcher_recipients) - recipients
|
||||
@note = note
|
||||
@note_url = url_for(:controller => 'notes', :action => 'show', :id => note.id)
|
||||
mail :to => recipients,
|
||||
:cc => cc,
|
||||
:subject => "[#{note.source.project.name}] - #{l(:label_crm_note_for)} #{note.source.name}"
|
||||
end
|
||||
|
||||
def crm_contact_add(contact)
|
||||
redmine_headers 'Project' => contact.project.identifier,
|
||||
'X-Contact-Id' => contact.id
|
||||
@author = contact.author
|
||||
message_id contact
|
||||
recipients = contact.recipients
|
||||
cc = contact.watcher_recipients - recipients
|
||||
@contact = contact
|
||||
@contact_url = url_for(:controller => 'contacts', :action => 'show', :id => contact.id)
|
||||
mail :to => recipients,
|
||||
:cc => cc,
|
||||
:subject => "[#{contact.project.name} - #{l(:label_contact)} ##{contact.id}] #{contact.name}"
|
||||
end
|
||||
def crm_deal_add(deal)
|
||||
redmine_headers 'Project' => deal.project.identifier,
|
||||
'X-Deal-Id' => deal.id
|
||||
@author = deal.author
|
||||
message_id deal
|
||||
recipients = deal.recipients
|
||||
cc = deal.watcher_recipients - recipients
|
||||
@deal = deal
|
||||
@deal_url = url_for(:controller => 'deals', :action => 'show', :id => deal.id)
|
||||
mail :to => recipients,
|
||||
:cc => cc,
|
||||
:subject => "[#{deal.project.name} - #{l(:label_deal)} ##{deal.id}] #{deal.full_name}"
|
||||
end
|
||||
|
||||
def crm_deal_updated(deal_process)
|
||||
@deal = deal_process.deal
|
||||
redmine_headers 'Project' => @deal.project.identifier,
|
||||
'X-Deal-Id' => @deal.id
|
||||
@author = deal_process.author
|
||||
recipients = deal_process.recipients
|
||||
cc = @deal.watcher_recipients - recipients
|
||||
@status_was = deal_process.from
|
||||
@status = deal_process.to
|
||||
@deal_url = url_for(:controller => 'deals', :action => 'show', :id => @deal.id)
|
||||
mail :to => recipients,
|
||||
:cc => cc,
|
||||
:subject => "[#{@deal.project.name} - #{l(:label_deal)} ##{@deal.id}] #{@deal.full_name}"
|
||||
end
|
||||
|
||||
def crm_issue_connected(issue, contact)
|
||||
redmine_headers 'X-Project' => contact.project.identifier,
|
||||
'X-Issue-Id' => issue.id,
|
||||
'X-Contact-Id' => contact.id
|
||||
message_id contact
|
||||
recipients contact.watcher_recipients
|
||||
subject "[#{contact.projects.first.name}] - #{l(:label_issue_for)} #{contact.name}"
|
||||
|
||||
body :contact => contact,
|
||||
:issue => issue,
|
||||
:contact_url => url_for(:controller => contact.class.name.pluralize.downcase, :action => 'show', :project_id => contact.project, :id => contact.id),
|
||||
:issue_url => url_for(:controller => "issues", :action => "show", :id => issue)
|
||||
render_multipart('issue_connected', body)
|
||||
end
|
||||
end
|
||||
|
||||
def self.included(receiver)
|
||||
receiver.extend ClassMethods
|
||||
receiver.send :include, InstanceMethods
|
||||
receiver.class_eval do
|
||||
unloadable
|
||||
# TODO: Удалено из-за несовместимости, может быть косяк с шаблонами для майлера
|
||||
# self.instance_variable_get("@inheritable_attributes")[:view_paths] << RAILS_ROOT + "/vendor/plugins/redmine_contacts/app/views"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
unless Mailer.included_modules.include?(RedmineContacts::Patches::MailerPatch)
|
||||
Mailer.send(:include, RedmineContacts::Patches::MailerPatch)
|
||||
end
|
||||
@@ -0,0 +1,52 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
module RedmineContacts
|
||||
module Patches
|
||||
module NotifiablePatch
|
||||
def self.included(base)
|
||||
base.extend(ClassMethods)
|
||||
base.class_eval do
|
||||
unloadable
|
||||
class << self
|
||||
alias_method :all_without_contacts, :all
|
||||
alias_method :all, :all_with_contacts
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
# include ContactsHelper
|
||||
|
||||
def all_with_contacts
|
||||
notifications = all_without_contacts
|
||||
notifications << Redmine::Notifiable.new('crm_contact_added')
|
||||
notifications << Redmine::Notifiable.new('crm_deal_added')
|
||||
notifications << Redmine::Notifiable.new('crm_deal_updated')
|
||||
notifications << Redmine::Notifiable.new('crm_note_added')
|
||||
notifications
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
unless Redmine::Notifiable.included_modules.include?(RedmineContacts::Patches::NotifiablePatch)
|
||||
Redmine::Notifiable.send(:include, RedmineContacts::Patches::NotifiablePatch)
|
||||
end
|
||||
@@ -0,0 +1,47 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
module RedmineContacts
|
||||
module Patches
|
||||
module ProjectPatch
|
||||
def self.included(base) # :nodoc:
|
||||
base.class_eval do
|
||||
unloadable # Send unloadable so it will not be unloaded in development
|
||||
|
||||
has_many :deals, :dependent => :delete_all
|
||||
if ActiveRecord::VERSION::MAJOR >= 4
|
||||
has_and_belongs_to_many :contacts, lambda { order("#{Contact.table_name}.last_name, #{Contact.table_name}.first_name") }
|
||||
|
||||
has_many :deal_categories, lambda { order("#{DealCategory.table_name}.name") }, :dependent => :delete_all
|
||||
has_and_belongs_to_many :deal_statuses, lambda { order("#{DealStatus.table_name}.status_type, #{DealStatus.table_name}.position") }
|
||||
else
|
||||
has_and_belongs_to_many :contacts, :order => "#{Contact.table_name}.last_name, #{Contact.table_name}.first_name"
|
||||
|
||||
has_many :deal_categories, :order => "#{DealCategory.table_name}.name", :dependent => :delete_all
|
||||
has_and_belongs_to_many :deal_statuses, :order => "#{DealStatus.table_name}.status_type, #{DealStatus.table_name}.position", :uniq => true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
unless Project.included_modules.include?(RedmineContacts::Patches::ProjectPatch)
|
||||
Project.send(:include, RedmineContacts::Patches::ProjectPatch)
|
||||
end
|
||||
@@ -0,0 +1,58 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
require_dependency 'queries_helper'
|
||||
|
||||
module RedmineContacts
|
||||
module Patches
|
||||
module ProjectsHelperPatch
|
||||
def self.included(base)
|
||||
base.send(:include, InstanceMethods)
|
||||
|
||||
base.class_eval do
|
||||
unloadable
|
||||
alias_method :project_settings_tabs_without_contacts, :project_settings_tabs
|
||||
alias_method :project_settings_tabs, :project_settings_tabs_with_contacts
|
||||
end
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
# include ContactsHelper
|
||||
|
||||
def project_settings_tabs_with_contacts
|
||||
tabs = project_settings_tabs_without_contacts
|
||||
|
||||
tabs.push(:name => 'contacts',
|
||||
:action => :manage_contacts,
|
||||
:partial => 'projects/contacts_settings',
|
||||
:label => :label_contact_plural) if User.current.allowed_to?(:manage_contacts, @project)
|
||||
tabs.push(:name => 'deals',
|
||||
:action => :manage_deals,
|
||||
:partial => 'projects/deals_settings',
|
||||
:label => :label_deal_plural) if User.current.allowed_to?(:manage_deals, @project)
|
||||
tabs
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
unless ProjectsHelper.included_modules.include?(RedmineContacts::Patches::ProjectsHelperPatch)
|
||||
ProjectsHelper.send(:include, RedmineContacts::Patches::ProjectsHelperPatch)
|
||||
end
|
||||
@@ -0,0 +1,76 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
require_dependency 'queries_helper'
|
||||
|
||||
module RedmineContacts
|
||||
module Patches
|
||||
module QueriesHelperPatch
|
||||
def self.included(base)
|
||||
base.send(:include, InstanceMethods)
|
||||
|
||||
base.class_eval do
|
||||
unloadable
|
||||
alias_method :column_value_without_contacts, :column_value
|
||||
alias_method :column_value, :column_value_with_contacts
|
||||
end
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
def column_value_with_contacts(column, list_object, value)
|
||||
if column.name == :id && list_object.is_a?(Contact)
|
||||
link_to(value, contact_path(value))
|
||||
elsif column.name == :name && list_object.is_a?(Contact)
|
||||
contact_tag(list_object)
|
||||
elsif column.name == :name && list_object.is_a?(Deal)
|
||||
link_to(list_object.name, deal_path(list_object))
|
||||
elsif column.name == :price && list_object.is_a?(Deal)
|
||||
list_object.price_to_s
|
||||
elsif column.name == :expected_revenue && list_object.is_a?(Deal)
|
||||
list_object.expected_revenue_to_s
|
||||
elsif column.name == :probability && !value.blank? && list_object.is_a?(Deal)
|
||||
"#{value.to_i}%"
|
||||
elsif value.is_a?(Deal)
|
||||
deal_tag(value, :no_contact => true, :plain => true)
|
||||
elsif value.is_a?(Contact)
|
||||
contact_tag(value)
|
||||
elsif column.name == :contacts
|
||||
contacts_span = []
|
||||
[value].flatten.each do |contact|
|
||||
contacts_span << contact_tag(contact)
|
||||
end
|
||||
contacts_span.join(', ').html_safe
|
||||
elsif column.name == :tags && list_object.is_a?(Contact)
|
||||
contact_tags = []
|
||||
[value].flatten.each do |tag|
|
||||
contact_tags << tag.name
|
||||
end
|
||||
contact_tags.join(', ')
|
||||
else
|
||||
column_value_without_contacts(column, list_object, value)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
unless QueriesHelper.included_modules.include?(RedmineContacts::Patches::QueriesHelperPatch)
|
||||
QueriesHelper.send(:include, RedmineContacts::Patches::QueriesHelperPatch)
|
||||
end
|
||||
@@ -0,0 +1,44 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
require_dependency 'query'
|
||||
|
||||
module RedmineContacts
|
||||
module Patches
|
||||
module QueryFilterPatch
|
||||
def self.included(base)
|
||||
base.send(:include, InstanceMethods)
|
||||
base.class_eval do
|
||||
unloadable
|
||||
end
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
def []=(key, value)
|
||||
return unless key == :values
|
||||
@value = @options[:values] = value
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
unless QueryFilter.included_modules.include?(RedmineContacts::Patches::QueryFilterPatch)
|
||||
QueryFilter.send(:include, RedmineContacts::Patches::QueryFilterPatch)
|
||||
end
|
||||
@@ -0,0 +1,68 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
require_dependency 'query'
|
||||
|
||||
module RedmineContacts
|
||||
module Patches
|
||||
module QueryPatch
|
||||
def self.included(base)
|
||||
base.send(:include, InstanceMethods)
|
||||
base.class_eval do
|
||||
unloadable
|
||||
|
||||
alias_method :add_filter_without_contacts, :add_filter
|
||||
alias_method :add_filter, :add_filter_with_contacts
|
||||
|
||||
alias_method :available_filters_as_json_without_contacts, :available_filters_as_json
|
||||
alias_method :available_filters_as_json, :available_filters_as_json_with_contacts
|
||||
end
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
def add_filter_with_contacts(field, operator, values = nil)
|
||||
add_filter_without_contacts(field, operator, values)
|
||||
|
||||
if available_filters[field] && %w(company contact deal).include?(available_filters[field][:field_format])
|
||||
filter_options = available_filters[field]
|
||||
# Method :contact_query_values should be defined in query class for model
|
||||
if respond_to?(:contact_query_values)
|
||||
filter_options[:values] = contact_query_values(:field => field, :values => values)
|
||||
end
|
||||
return if filter_options[:values].present?
|
||||
filter_options[:values] = default_contact_query_values(:field => field, :values => values)
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
def available_filters_as_json_with_contacts
|
||||
json_data = available_filters_as_json_without_contacts
|
||||
Hash[json_data.map do |f_name, f_data|
|
||||
f_data['field_format'] = available_filters[f_name][:field_format]
|
||||
[f_name, f_data]
|
||||
end]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
unless Query.included_modules.include?(RedmineContacts::Patches::QueryPatch)
|
||||
Query.send(:include, RedmineContacts::Patches::QueryPatch)
|
||||
end
|
||||
@@ -0,0 +1,73 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
module RedmineContacts
|
||||
module Patches
|
||||
module SettingPatch
|
||||
def self.included(base)
|
||||
base.extend(ClassMethods)
|
||||
# base.send(:include, InstanceMethods)
|
||||
|
||||
base.class_eval do
|
||||
unloadable
|
||||
# Setting.available_settings["disable_taxes"] = {'default' => 0}
|
||||
# @@available_settings["disable_taxes"] = {}
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
|
||||
# Setting.available_settings["disable_taxes"] = {}
|
||||
|
||||
# def disable_taxes?
|
||||
# self[:disable_taxes].to_i > 0
|
||||
# end
|
||||
|
||||
# def disable_taxes=(value)
|
||||
# self[:disable_taxes] = value
|
||||
# end
|
||||
|
||||
%w(disable_taxes default_tax tax_type default_currency money_thousands_delimiter money_decimal_separator).each do |name|
|
||||
src = <<-END_SRC
|
||||
Setting.available_settings["#{name}"] = ""
|
||||
|
||||
def #{name}
|
||||
self[:#{name}]
|
||||
end
|
||||
|
||||
def #{name}?
|
||||
self[:#{name}].to_i > 0
|
||||
end
|
||||
|
||||
def #{name}=(value)
|
||||
self[:#{name}] = value
|
||||
end
|
||||
END_SRC
|
||||
class_eval src, __FILE__, __LINE__
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
unless Setting.included_modules.include?(RedmineContacts::Patches::SettingPatch)
|
||||
Setting.send(:include, RedmineContacts::Patches::SettingPatch)
|
||||
end
|
||||
@@ -0,0 +1,51 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
module RedmineContacts
|
||||
module Patches
|
||||
module SettingsHelperPatch
|
||||
def self.included(base)
|
||||
base.send(:include, InstanceMethods)
|
||||
|
||||
base.class_eval do
|
||||
unloadable
|
||||
|
||||
alias_method :administration_settings_tabs_without_contacts, :administration_settings_tabs
|
||||
alias_method :administration_settings_tabs, :administration_settings_tabs_with_contacts
|
||||
end
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
# include ContactsHelper
|
||||
|
||||
def administration_settings_tabs_with_contacts
|
||||
tabs = administration_settings_tabs_without_contacts
|
||||
|
||||
tabs.push(:name => 'money',
|
||||
:partial => 'settings/contacts/money',
|
||||
:label => :label_crm_money_settings)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
unless SettingsHelper.included_modules.include?(RedmineContacts::Patches::SettingsHelperPatch)
|
||||
SettingsHelper.send(:include, RedmineContacts::Patches::SettingsHelperPatch)
|
||||
end
|
||||
@@ -0,0 +1,45 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
require_dependency 'query'
|
||||
|
||||
module RedmineContacts
|
||||
module Patches
|
||||
module TimeEntryQueryPatch
|
||||
def self.included(base)
|
||||
base.send(:include, InstanceMethods)
|
||||
base.send(:include, RedmineContacts::Helper)
|
||||
|
||||
base.class_eval do
|
||||
unloadable
|
||||
end
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
def contact_query_values(options = {})
|
||||
contacts_for_select(nil, :where => { :id => options[:values] }, :short_label => true)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
unless TimeEntryQuery.included_modules.include?(RedmineContacts::Patches::TimeEntryQueryPatch)
|
||||
TimeEntryQuery.send(:include, RedmineContacts::Patches::TimeEntryQueryPatch)
|
||||
end
|
||||
@@ -0,0 +1,54 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
module RedmineContacts
|
||||
module Patches
|
||||
module TimeReportPatch
|
||||
def self.included(base)
|
||||
base.send(:include, InstanceMethods)
|
||||
|
||||
base.class_eval do
|
||||
unloadable
|
||||
alias_method :load_available_criteria_without_contacts, :load_available_criteria
|
||||
alias_method :load_available_criteria, :load_available_criteria_with_contacts
|
||||
end
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
def load_available_criteria_with_contacts
|
||||
@available_criteria = load_available_criteria_without_contacts
|
||||
@available_criteria['deal'] = { :sql => 'd_deals_issues.deal_id',
|
||||
:kclass => Deal,
|
||||
:joins => 'LEFT OUTER JOIN deals_issues d_deals_issues ON d_deals_issues.issue_id = issues.id',
|
||||
:label => :label_deal } if User.current.allowed_to?(:view_deals, @project, :global => true)
|
||||
@available_criteria['deal_contact'] = { :sql => 'd_deals.contact_id',
|
||||
:kclass => Contact,
|
||||
:joins => 'LEFT OUTER JOIN deals_issues c_deals_issues ON c_deals_issues.issue_id = issues.id
|
||||
LEFT OUTER JOIN deals d_deals ON c_deals_issues.deal_id = d_deals.id',
|
||||
:label => :label_crm_deal_contact } if User.current.allowed_to?(:view_deals, @project, :global => true)
|
||||
@available_criteria
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
unless Redmine::Helpers::TimeReport.included_modules.include?(RedmineContacts::Patches::TimeReportPatch)
|
||||
Redmine::Helpers::TimeReport.send(:include, RedmineContacts::Patches::TimeReportPatch)
|
||||
end
|
||||
@@ -0,0 +1,50 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
module RedmineContacts
|
||||
module Patches
|
||||
module TimelogHelperPatch
|
||||
def self.included(base)
|
||||
base.send(:include, InstanceMethods)
|
||||
|
||||
base.class_eval do
|
||||
unloadable
|
||||
alias_method :format_criteria_value_without_contacts, :format_criteria_value
|
||||
alias_method :format_criteria_value, :format_criteria_value_with_contacts
|
||||
end
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
def format_criteria_value_with_contacts(criteria_options, value)
|
||||
if !value.blank? && criteria_options[:kclass] == Contact && obj = Contact.find_by_id(value.to_i)
|
||||
obj.visible? ? obj.name : "#{l(:label_contact)} - ##{obj.id}"
|
||||
elsif !value.blank? && criteria_options[:kclass] == Deal && obj = Deal.find_by_id(value.to_i)
|
||||
obj.visible? ? "#{obj.full_name} (#{obj.info})" : "#{l(:label_deal)} - ##{obj.id}"
|
||||
else
|
||||
format_criteria_value_without_contacts(criteria_options, value)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
unless TimelogHelper.included_modules.include?(RedmineContacts::Patches::TimelogHelperPatch)
|
||||
TimelogHelper.send(:include, RedmineContacts::Patches::TimelogHelperPatch)
|
||||
end
|
||||
@@ -0,0 +1,51 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
require_dependency 'users_controller'
|
||||
require_dependency 'user'
|
||||
|
||||
module RedmineContacts
|
||||
module Patches
|
||||
module UsersControllerPatch
|
||||
def self.included(base) # :nodoc:
|
||||
base.class_eval do
|
||||
end
|
||||
base.send(:include, InstanceMethods)
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
def new_from_contact
|
||||
contact = Contact.visible.find(params[:contact_id])
|
||||
@user = User.new(:language => Setting.default_language, :mail_notification => Setting.default_notification_option)
|
||||
@user.firstname = contact.first_name
|
||||
@user.lastname = contact.last_name
|
||||
@user.mail = contact.emails.first
|
||||
@auth_sources = AuthSource.all
|
||||
respond_to do |format|
|
||||
format.html { render :action => 'new' }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
unless UsersController.included_modules.include?(RedmineContacts::Patches::UsersControllerPatch)
|
||||
UsersController.send(:include, RedmineContacts::Patches::UsersControllerPatch)
|
||||
end
|
||||
@@ -0,0 +1,120 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
require 'net/imap'
|
||||
require 'net/pop'
|
||||
require 'openssl'
|
||||
require 'timeout'
|
||||
|
||||
module RedmineContacts
|
||||
module Mailer
|
||||
class << self
|
||||
|
||||
def check_imap(mailer, imap_options={}, options={})
|
||||
host = imap_options[:host] || '127.0.0.1'
|
||||
port = imap_options[:port] || '143'
|
||||
ssl = !imap_options[:ssl].nil?
|
||||
folder = imap_options[:folder] || 'INBOX'
|
||||
|
||||
Timeout::timeout(15) do
|
||||
@imap = Net::IMAP.new(host, port, ssl)
|
||||
@imap.login(imap_options[:username], imap_options[:password]) unless imap_options[:username].nil?
|
||||
end
|
||||
|
||||
@imap.select(folder)
|
||||
msg_count = 0
|
||||
|
||||
@imap.uid_search(['NOT', 'SEEN']).each do |uid|
|
||||
msg = @imap.uid_fetch(uid,'RFC822')[0].attr['RFC822']
|
||||
logger.info "ContactsMailHandler: Receiving message #{uid}" if logger && logger.info?
|
||||
msg_count += 1
|
||||
|
||||
if mailer.receive(msg, options)
|
||||
logger.info "ContactsMailHandler: Message #{uid} successfully received" if logger && logger.info?
|
||||
if imap_options[:move_on_success] && imap_options[:move_on_success] != folder
|
||||
@imap.uid_copy(uid, imap_options[:move_on_success])
|
||||
end
|
||||
@imap.uid_store(uid, "+FLAGS", [:Seen, :Deleted])
|
||||
else
|
||||
logger.info "ContactsMailHandler: Message #{uid} can not be processed" if logger && logger.info?
|
||||
@imap.uid_store(uid, "+FLAGS", [:Seen])
|
||||
if imap_options[:move_on_failure]
|
||||
@imap.uid_copy(uid, imap_options[:move_on_failure])
|
||||
@imap.uid_store(uid, "+FLAGS", [:Deleted])
|
||||
end
|
||||
end
|
||||
end
|
||||
@imap.expunge
|
||||
msg_count
|
||||
ensure
|
||||
if defined?(@imap) && @imap && !@imap.disconnected?
|
||||
@imap.disconnect
|
||||
end
|
||||
end
|
||||
|
||||
def check_pop3(mailer, pop_options={}, options={})
|
||||
|
||||
host = pop_options[:host] || '127.0.0.1'
|
||||
port = pop_options[:port] || '110'
|
||||
apop = (pop_options[:apop].to_s == '1')
|
||||
delete_unprocessed = (pop_options[:delete_unprocessed].to_s == '1')
|
||||
|
||||
pop = Net::POP3.APOP(apop).new(host,port)
|
||||
pop.enable_ssl(OpenSSL::SSL::VERIFY_NONE) if pop_options[:ssl]
|
||||
logger.info "ContactsMailHandler: Connecting to #{host}..." if logger && logger.info?
|
||||
msg_count = 0
|
||||
pop.start(pop_options[:username], pop_options[:password]) do |pop_session|
|
||||
if pop_session.mails.empty?
|
||||
logger.info "ContactsMailHandler: No email to process" if logger && logger.info?
|
||||
else
|
||||
logger.info "ContactsMailHandler: #{pop_session.mails.size} email(s) to process..." if logger && logger.info?
|
||||
pop_session.each_mail do |msg|
|
||||
msg_count += 1
|
||||
message = msg.pop(String.new)
|
||||
uid = (message =~ /^Message-ID: (.*)/ ? $1 : '').strip
|
||||
if mailer.receive(message, options)
|
||||
msg.delete
|
||||
logger.info "--> ContactsMailHandler: Message #{uid} processed and deleted from the server" if logger && logger.info?
|
||||
else
|
||||
if delete_unprocessed
|
||||
msg.delete
|
||||
logger.info "--> ContactsMailHandler: Message #{uid} NOT processed and deleted from the server" if logger && logger.info?
|
||||
else
|
||||
logger.info "--> ContactsMailHandler: Message #{uid} NOT processed and left on the server" if logger && logger.info?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
msg_count
|
||||
ensure
|
||||
if defined?(pop) && pop && pop.started?
|
||||
pop.finish
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def logger
|
||||
::Rails.logger
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,49 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
module RedmineContacts
|
||||
module CSVUtils
|
||||
include Redmine::I18n
|
||||
|
||||
class << self
|
||||
|
||||
def csv_custom_value(custom_value)
|
||||
return "" unless custom_value
|
||||
value = custom_value.value
|
||||
case custom_value.custom_field.field_format
|
||||
when 'date'
|
||||
begin; format_date(value.to_date); rescue; value end
|
||||
when 'bool'
|
||||
l(value == "1" ? :general_text_Yes : :general_text_No)
|
||||
when 'float'
|
||||
sprintf("%.2f", value).gsub('.', l(:general_csv_decimal_separator))
|
||||
else
|
||||
if value.is_a?(Array)
|
||||
value.map(&:to_s).join(', ')
|
||||
else
|
||||
value.to_s
|
||||
end
|
||||
end
|
||||
rescue
|
||||
return ""
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,67 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
module RedmineContacts
|
||||
module DateUtils
|
||||
class << self
|
||||
def retrieve_date_range(period)
|
||||
from, to = nil, nil
|
||||
case period
|
||||
when 'today'
|
||||
from = to = Date.today
|
||||
when 'yesterday'
|
||||
from = to = Date.today - 1
|
||||
when 'current_week'
|
||||
from = Date.today - (Date.today.cwday - 1)%7
|
||||
to = from + 6
|
||||
when 'last_week'
|
||||
from = Date.today - 7 - (Date.today.cwday - 1)%7
|
||||
to = from + 6
|
||||
when 'last_2_weeks'
|
||||
from = Date.today - 14 - (Date.today.cwday - 1)%7
|
||||
to = from + 13
|
||||
when '7_days'
|
||||
from = Date.today - 7
|
||||
to = Date.today
|
||||
when 'last_7_days'
|
||||
from = Date.today - 14
|
||||
to = from + 7
|
||||
when 'current_month'
|
||||
from = Date.civil(Date.today.year, Date.today.month, 1)
|
||||
to = (from >> 1) - 1
|
||||
when 'last_month'
|
||||
from = Date.civil(Date.today.year, Date.today.month, 1) << 1
|
||||
to = (from >> 1) - 1
|
||||
when '30_days'
|
||||
from = Date.today - 30
|
||||
to = Date.today
|
||||
when 'current_year'
|
||||
from = Date.civil(Date.today.year, 1, 1)
|
||||
to = Date.civil(Date.today.year, 12, 31)
|
||||
when 'last_year'
|
||||
from = Date.civil(1.year.ago.year, 1, 1)
|
||||
to = Date.civil(1.year.ago.year, 12, 31)
|
||||
end
|
||||
|
||||
from, to = from, to + 1 if (from && to)
|
||||
[from, to]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,51 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
require 'fileutils'
|
||||
|
||||
module RedmineContacts
|
||||
module Thumbnail
|
||||
extend Redmine::Utils::Shell
|
||||
include Redmine::Thumbnail
|
||||
|
||||
CONVERT_BIN = (Redmine::Configuration['imagemagick_convert_command'] || 'convert').freeze
|
||||
|
||||
# Generates a thumbnail for the source image to target
|
||||
def self.generate(source, target, size)
|
||||
return nil unless Redmine::Thumbnail.convert_available?
|
||||
unless File.exists?(target)
|
||||
directory = File.dirname(target)
|
||||
unless File.exists?(directory)
|
||||
FileUtils.mkdir_p directory
|
||||
end
|
||||
size_option = "#{size}x#{size}^"
|
||||
sharpen_option = "0.7x6"
|
||||
crop_option = "#{size}x#{size}"
|
||||
cmd = "#{shell_quote CONVERT_BIN} #{shell_quote source} -resize #{shell_quote size_option} -sharpen #{shell_quote sharpen_option} -gravity center -extent #{shell_quote crop_option} #{shell_quote target}"
|
||||
unless system(cmd)
|
||||
Rails.logger.error("Creating thumbnail failed (#{$?}):\nCommand: #{cmd}")
|
||||
return nil
|
||||
end
|
||||
end
|
||||
target
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,87 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
module RedmineContacts
|
||||
module WikiMacros
|
||||
Redmine::WikiFormatting::Macros.register do
|
||||
|
||||
desc "Contact Description Macro"
|
||||
macro :contact_plain do |obj, args|
|
||||
args, options = extract_macro_options(args, :parent)
|
||||
raise 'No or bad arguments.' if args.size != 1
|
||||
if args.first && args.first.is_a?(String) && !args.first.match(/^\d*$/)
|
||||
first_name, last_name = args.first.split
|
||||
conditions = {:first_name => first_name}
|
||||
conditions[:last_name] = last_name if last_name
|
||||
contact = Contact.visible.find(:first, :conditions => conditions)
|
||||
else
|
||||
contact = Contact.visible.find_by_id(args.first)
|
||||
end
|
||||
link_to_source(contact) if contact
|
||||
end
|
||||
|
||||
desc "Contact avatar"
|
||||
macro :contact_avatar do |obj, args|
|
||||
args, options = extract_macro_options(args, :parent)
|
||||
raise 'No or bad arguments.' if args.size != 1
|
||||
if args.first && args.first.is_a?(String) && !args.first.match(/^\d*$/)
|
||||
first_name, last_name = args.first.split
|
||||
conditions = {:first_name => first_name}
|
||||
conditions[:last_name] = last_name if last_name
|
||||
contact = Contact.visible.find(:first, :conditions => conditions)
|
||||
else
|
||||
contact = Contact.visible.find_by_id(args.first)
|
||||
end
|
||||
link_to avatar_to(contact, :size => "32"), contact_path(contact), :id => "avatar", :title => contact.name if contact
|
||||
end
|
||||
|
||||
desc "Contact with avatar"
|
||||
macro :contact do |obj, args|
|
||||
args, options = extract_macro_options(args, :parent)
|
||||
raise 'No or bad arguments.' if args.size != 1
|
||||
if args.first && args.first.is_a?(String) && !args.first.match(/^\d*$/)
|
||||
first_name, last_name = args.first.split
|
||||
conditions = {:first_name => first_name}
|
||||
conditions[:last_name] = last_name if last_name
|
||||
contact = Contact.visible.find(:first, :conditions => conditions)
|
||||
else
|
||||
contact = Contact.visible.find_by_id(args.first)
|
||||
end
|
||||
contact_tag(contact) if contact
|
||||
end
|
||||
|
||||
desc "Contact/Deal note"
|
||||
macro :contact_note do |obj, args|
|
||||
args, options = extract_macro_options(args, :parent)
|
||||
raise 'No or bad arguments.' if args.size != 1
|
||||
note = Note.find_by_id(args.first)
|
||||
textilizable(note, :content).html_safe if note && note.source.visible?
|
||||
end
|
||||
desc "Deal"
|
||||
macro :deal do |obj, args|
|
||||
args, options = extract_macro_options(args, :parent)
|
||||
raise 'No or bad arguments.' if args.size != 1
|
||||
deal = Deal.visible.find(args.first)
|
||||
deal_tag(deal)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user