sp-duh 2.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +661 -0
- data/README.md +2 -0
- data/Rakefile +32 -0
- data/config/i18n/i18n.xlsx +0 -0
- data/config/initializers/active_record/connection_adapters_postgre_sql_adapter.rb +165 -0
- data/config/initializers/active_record/migration_without_transaction.rb +4 -0
- data/config/initializers/active_record/migrator.rb +34 -0
- data/config/initializers/rails/generators.rb +13 -0
- data/config/jsonapi/settings.yml +14 -0
- data/config/locales/pt.yml +15 -0
- data/lib/generators/accounting_migration/accounting_migration_generator.rb +10 -0
- data/lib/generators/accounting_migration/templates/migration.rb +42 -0
- data/lib/generators/accounting_payroll_migration/accounting_payroll_migration_generator.rb +10 -0
- data/lib/generators/accounting_payroll_migration/templates/migration.rb +73 -0
- data/lib/generators/sharded_migration/sharded_migration_generator.rb +10 -0
- data/lib/generators/sharded_migration/templates/migration.rb +45 -0
- data/lib/sp-duh.rb +32 -0
- data/lib/sp/duh.rb +180 -0
- data/lib/sp/duh/adapters/pg/text_decoder/json.rb +15 -0
- data/lib/sp/duh/adapters/pg/text_encoder/json.rb +15 -0
- data/lib/sp/duh/db/transfer/backup.rb +71 -0
- data/lib/sp/duh/db/transfer/restore.rb +89 -0
- data/lib/sp/duh/engine.rb +35 -0
- data/lib/sp/duh/exceptions.rb +70 -0
- data/lib/sp/duh/i18n/excel_loader.rb +26 -0
- data/lib/sp/duh/jsonapi/adapters/base.rb +168 -0
- data/lib/sp/duh/jsonapi/adapters/db.rb +36 -0
- data/lib/sp/duh/jsonapi/adapters/raw_db.rb +77 -0
- data/lib/sp/duh/jsonapi/configuration.rb +167 -0
- data/lib/sp/duh/jsonapi/doc/apidoc_documentation_format_generator.rb +286 -0
- data/lib/sp/duh/jsonapi/doc/generator.rb +32 -0
- data/lib/sp/duh/jsonapi/doc/schema_catalog_helper.rb +97 -0
- data/lib/sp/duh/jsonapi/doc/victor_pinus_metadata_format_parser.rb +374 -0
- data/lib/sp/duh/jsonapi/exceptions.rb +56 -0
- data/lib/sp/duh/jsonapi/model/base.rb +25 -0
- data/lib/sp/duh/jsonapi/model/concerns/attributes.rb +94 -0
- data/lib/sp/duh/jsonapi/model/concerns/model.rb +42 -0
- data/lib/sp/duh/jsonapi/model/concerns/persistence.rb +221 -0
- data/lib/sp/duh/jsonapi/model/concerns/serialization.rb +59 -0
- data/lib/sp/duh/jsonapi/parameters.rb +44 -0
- data/lib/sp/duh/jsonapi/resource_publisher.rb +28 -0
- data/lib/sp/duh/jsonapi/service.rb +110 -0
- data/lib/sp/duh/migrations.rb +47 -0
- data/lib/sp/duh/migrations/migrator.rb +41 -0
- data/lib/sp/duh/repl.rb +193 -0
- data/lib/sp/duh/version.rb +25 -0
- data/lib/tasks/db_utils.rake +98 -0
- data/lib/tasks/doc.rake +27 -0
- data/lib/tasks/i18n.rake +23 -0
- data/lib/tasks/oauth.rake +29 -0
- data/lib/tasks/transfer.rake +48 -0
- data/lib/tasks/xls2jrxml.rake +15 -0
- data/test/jsonapi/server.rb +67 -0
- data/test/tasks/test.rake +10 -0
- metadata +170 -0
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
#
|
3
|
+
# Copyright (c) 2011-2017 Cloudware S.A. All rights reserved.
|
4
|
+
#
|
5
|
+
# This file is part of sp-duh.
|
6
|
+
#
|
7
|
+
# sp-duh is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU Affero General Public License as published by
|
9
|
+
# the Free Software Foundation, either version 3 of the License, or
|
10
|
+
# (at your option) any later version.
|
11
|
+
#
|
12
|
+
# sp-duh is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU Affero General Public License
|
18
|
+
# along with sp-duh. If not, see <http://www.gnu.org/licenses/>.
|
19
|
+
#
|
20
|
+
# encoding: utf-8
|
21
|
+
#
|
22
|
+
require "bundler/gem_tasks"
|
23
|
+
require 'sp-duh'
|
24
|
+
|
25
|
+
load 'lib/tasks/db_utils.rake'
|
26
|
+
load 'lib/tasks/i18n.rake'
|
27
|
+
load 'lib/tasks/xls2jrxml.rake'
|
28
|
+
|
29
|
+
# Allow calling common tasks either from the app (using its environment) or locally from the gem
|
30
|
+
# In this case, open the connection to the database
|
31
|
+
task :environment => :pg_connect do
|
32
|
+
end
|
Binary file
|
@@ -0,0 +1,165 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module ConnectionAdapters
|
3
|
+
class PostgreSQLAdapter
|
4
|
+
def active?
|
5
|
+
true
|
6
|
+
end
|
7
|
+
|
8
|
+
def initialize_with_redis_connection(connection, logger, connection_parameters, config)
|
9
|
+
@redis_connection = Rails.application.redis.optimizations.instance_variable_get(:@data)
|
10
|
+
initialize_without_redis_connection(connection, logger, connection_parameters, config)
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def configure_connection_with_mappings
|
16
|
+
# Build Ruby <-> PostgreSQL type mappings
|
17
|
+
results_map = PG::BasicTypeMapForResults.new(@connection, @redis_connection)
|
18
|
+
queries_map = PG::BasicTypeMapForQueries.new(@connection, @redis_connection)
|
19
|
+
|
20
|
+
# Add a decoder for the NUMERIC PostgreSQL data type
|
21
|
+
results_map.add_coder PG::TextDecoder::Float.new(oid: 1700, name: 'float8')
|
22
|
+
# Fix: Warning: no type cast defined for type "name" with oid 19. Please cast this type explicitly to TEXT to be safe for future changes.
|
23
|
+
results_map.add_coder PG::TextDecoder::String.new(oid: 19, name: 'text')
|
24
|
+
# Fix: Warning: no type cast defined for type "regproc" with oid 24. Please cast this type explicitly to TEXT to be safe for future changes.
|
25
|
+
results_map.add_coder PG::TextDecoder::String.new(oid: 24, name: 'text')
|
26
|
+
|
27
|
+
# Add decoders for the JSON and JSONB data types (using our custom decoder class)
|
28
|
+
results_map.add_coder SP::Duh::Adapters::PG::TextDecoder::Json.new(oid: 114, name: 'json')
|
29
|
+
results_map.add_coder SP::Duh::Adapters::PG::TextDecoder::Json.new(oid: 199, name: '_json')
|
30
|
+
results_map.add_coder SP::Duh::Adapters::PG::TextDecoder::Json.new(oid: 3802, name: 'jsonb')
|
31
|
+
results_map.add_coder SP::Duh::Adapters::PG::TextDecoder::Json.new(oid: 3807, name: '_jsonb')
|
32
|
+
|
33
|
+
# Fix: Remove decoder for Date and Timestamp
|
34
|
+
#<PG::TextDecoder::Date:0x0000000857dcf0 "date" oid=1082>,
|
35
|
+
results_map.rm_coder(0, 1082)
|
36
|
+
|
37
|
+
#<PG::TextDecoder::TimestampWithoutTimeZone:0x0000000857db38 "timestamp" oid=1114>,
|
38
|
+
results_map.rm_coder(0, 1114)
|
39
|
+
|
40
|
+
#<PG::TextDecoder::TimestampWithTimeZone:0x0000000857d958 "timestamptz" oid=1184>,
|
41
|
+
results_map.rm_coder(0, 1184)
|
42
|
+
|
43
|
+
#<PG::TextDecoder::Array:0x0000000868cdf8 "_timestamp" oid=1115>,
|
44
|
+
results_map.rm_coder(0, 1115)
|
45
|
+
|
46
|
+
#<PG::TextDecoder::Array:0x0000000868cd30 "_date" oid=1182>,
|
47
|
+
results_map.rm_coder(0, 1182)
|
48
|
+
|
49
|
+
#<PG::TextDecoder::Array:0x0000000868cc40 "_timestamptz" oid=1185>,
|
50
|
+
results_map.rm_coder(0, 1185)
|
51
|
+
|
52
|
+
# <PG::TextDecoder::Bytea:0x007f96afcc1aa8 "bytea" oid=17>,
|
53
|
+
results_map.rm_coder(0, 17)
|
54
|
+
|
55
|
+
# Set PostgreSQL type mappings
|
56
|
+
@connection.type_map_for_results = results_map
|
57
|
+
@connection.type_map_for_queries = queries_map
|
58
|
+
|
59
|
+
configure_connection_without_mappings
|
60
|
+
end
|
61
|
+
|
62
|
+
# Override methods to store catalog data in Redis
|
63
|
+
%w(column_definitions primary_key table_exists?).each do |method|
|
64
|
+
method_name, punctuation = method.to_s.sub(/([?!=])$/, ''), $1
|
65
|
+
|
66
|
+
class_eval <<-METHOD, __FILE__, __LINE__ + 1
|
67
|
+
def #{method_name}_with_redis_cache#{punctuation}(table_name)
|
68
|
+
if !!@redis_connection
|
69
|
+
@redis_connection.get("postgresql:#{method_name}:\#{table_name}") || begin
|
70
|
+
@redis_connection.set("postgresql:#{method_name}:\#{table_name}", d = #{method_name}_without_redis_cache#{punctuation}(table_name)) ; d
|
71
|
+
end
|
72
|
+
else
|
73
|
+
#{method_name}_without_redis_cache#{punctuation}(table_name)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
alias_method_chain :#{method}, :redis_cache
|
78
|
+
METHOD
|
79
|
+
end
|
80
|
+
|
81
|
+
def disable_referential_integrity_with_foreign_keys(&block)
|
82
|
+
if Rails.env.test?
|
83
|
+
transaction do
|
84
|
+
begin
|
85
|
+
execute "SET CONSTRAINTS ALL DEFERRED"
|
86
|
+
yield
|
87
|
+
ensure
|
88
|
+
execute "SET CONSTRAINTS ALL IMMEDIATE"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
else
|
92
|
+
disable_referential_integrity_without_foreign_keys &block
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
alias_method_chain :configure_connection, :mappings
|
97
|
+
alias_method_chain :disable_referential_integrity, :foreign_keys
|
98
|
+
alias_method_chain :initialize, :redis_connection
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# This module MUST be loaded before the #configure_connection_with_mappings method is called
|
104
|
+
module PG
|
105
|
+
class BasicTypeMapForResults
|
106
|
+
def initialize_with_redis_connection(connection, redis_connection = nil)
|
107
|
+
@redis_connection = redis_connection
|
108
|
+
initialize_without_redis_connection connection
|
109
|
+
end
|
110
|
+
|
111
|
+
alias_method_chain :initialize, :redis_connection
|
112
|
+
end
|
113
|
+
|
114
|
+
class BasicTypeMapForQueries
|
115
|
+
def initialize_with_redis_connection(connection, redis_connection = nil)
|
116
|
+
@redis_connection = redis_connection
|
117
|
+
initialize_without_redis_connection connection
|
118
|
+
end
|
119
|
+
|
120
|
+
alias_method_chain :initialize, :redis_connection
|
121
|
+
end
|
122
|
+
|
123
|
+
module BasicTypeRegistry
|
124
|
+
|
125
|
+
private
|
126
|
+
|
127
|
+
def build_coder_maps(connection)
|
128
|
+
if !!@redis_connection
|
129
|
+
@redis_connection.get('postgresql:coder-maps') || begin
|
130
|
+
@redis_connection.set('postgresql:coder-maps', m = get_coder_maps_from_database(connection)) ; m
|
131
|
+
end
|
132
|
+
else
|
133
|
+
get_coder_maps_from_database(connection)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def get_coder_maps_from_database(connection)
|
138
|
+
result = connection.exec(if supports_ranges?(connection)
|
139
|
+
<<-SQL
|
140
|
+
SELECT n.nspname, t.oid, t.typname, t.typelem, t.typdelim, t.typinput, r.rngsubtype
|
141
|
+
FROM pg_type as t
|
142
|
+
LEFT JOIN pg_range as r ON oid = rngtypid
|
143
|
+
LEFT JOIN pg_namespace n ON n.oid = t.typnamespace
|
144
|
+
WHERE n.nspname IN ('pg_catalog', 'public')
|
145
|
+
SQL
|
146
|
+
else
|
147
|
+
<<-SQL
|
148
|
+
SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput
|
149
|
+
FROM pg_type as t
|
150
|
+
SQL
|
151
|
+
end)
|
152
|
+
|
153
|
+
[
|
154
|
+
[0, :encoder, PG::TextEncoder::Array],
|
155
|
+
[0, :decoder, PG::TextDecoder::Array],
|
156
|
+
[1, :encoder, nil],
|
157
|
+
[1, :decoder, nil],
|
158
|
+
].inject([]) do |h, (format, direction, arraycoder)|
|
159
|
+
h[format] ||= {}
|
160
|
+
h[format][direction] = CoderMap.new result, CODERS_BY_NAME[format][direction], format, arraycoder
|
161
|
+
h
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
class Migrator
|
3
|
+
cattr_accessor :current_migration_for_transaction_test
|
4
|
+
|
5
|
+
ActiveRecord::Base.connection.instance_eval do
|
6
|
+
alias :old_supports_ddl_transactions? :supports_ddl_transactions?
|
7
|
+
|
8
|
+
def supports_ddl_transactions?
|
9
|
+
begin
|
10
|
+
require File.expand_path(ActiveRecord::Migrator.current_migration_for_transaction_test.filename)
|
11
|
+
|
12
|
+
if MigrationWithoutTransaction.in?(ActiveRecord::Migrator.current_migration_for_transaction_test.name.constantize.ancestors)
|
13
|
+
false
|
14
|
+
else
|
15
|
+
old_supports_ddl_transactions?
|
16
|
+
end
|
17
|
+
rescue
|
18
|
+
old_supports_ddl_transactions?
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
alias_method :old_migrate, :migrate
|
24
|
+
|
25
|
+
def migrate(&block)
|
26
|
+
ActiveRecord::Base.connection.raw_connection.type_map_for_results = PG::TypeMapAllStrings.new
|
27
|
+
ActiveRecord::Base.connection.raw_connection.type_map_for_queries = PG::TypeMapAllStrings.new
|
28
|
+
|
29
|
+
old_migrate do |migration|
|
30
|
+
(block.nil? ? true : block.call) && !(ActiveRecord::Migrator.current_migration_for_transaction_test = migration).nil?
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
|
3
|
+
module Rails
|
4
|
+
module Generators
|
5
|
+
class <<self
|
6
|
+
alias_method :original_invoke, :invoke
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.invoke(namespace, args=ARGV, config={})
|
10
|
+
original_invoke namespace.tr('-', '_'), args, config
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
version: false
|
2
|
+
compound: false
|
3
|
+
show-links: false
|
4
|
+
show-null: true
|
5
|
+
type-restriction: true
|
6
|
+
attribute-restriction: false
|
7
|
+
empty-is-null: true
|
8
|
+
page-size: 0
|
9
|
+
request-company-schema: false
|
10
|
+
request-sharded-schema: false
|
11
|
+
request-accounting-schema: false
|
12
|
+
request-accounting-prefix: false
|
13
|
+
pg-order-by: "created_at"
|
14
|
+
pg-search_path: '"$user", request-sharded-schema, public'
|
@@ -0,0 +1,15 @@
|
|
1
|
+
pt:
|
2
|
+
sp-duh:
|
3
|
+
exceptions:
|
4
|
+
jsonapi:
|
5
|
+
service_setup_error: 'O serviço JSONAPI não se encontra disponível porque os recursos não estão devidamente instalados.'
|
6
|
+
service_protocol_error: 'O protocolo definido para acesso ao serviço JSONAPI (%{protocol}) não é suportado. Os protocolos suportados são: %{protocols}.'
|
7
|
+
invalid_resource_configuration_error: 'A configuração de recursos definida no ficheiro %{file} é inválida.'
|
8
|
+
duplicate_resource_error: 'Tentativa de redefinção do recurso %{name}. O recurso já foi definido anteriormente.'
|
9
|
+
save_configuration_error: 'Erro ao gravar a configuração da JSONAPI na base de dados.'
|
10
|
+
invalid_resource_publisher_error: 'O módulo ou classe %{publisher} não é uma fonte de recursos JSONAPI válida.'
|
11
|
+
invalid_jsonapi_key_error: 'A chave %{key} não é válida para configurar a JSONAPI.'
|
12
|
+
sharding:
|
13
|
+
invalid_sharder_type_error: 'Erro de definição do particionamento para a partição %{namespace}: o tipo de partição pretendido, %{sharder_type}, não se encontra instalado.'
|
14
|
+
invalid_sharding_definition_error: 'Erro de definição do particionamento para a partição %{namespace}: não é possível aceder à estrutura de particionamento definida (%{shard_value_field} na estrutura %{shard_table} pelo id %{shard_id_field}).'
|
15
|
+
shard_not_found_error: 'Não existe a partição com o identificador %{shard_id} na estrutura %{shard_table} da partição %{namespace}.'
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'rails/generators/active_record/migration/migration_generator'
|
2
|
+
|
3
|
+
class AccountingMigrationGenerator < ActiveRecord::Generators::MigrationGenerator
|
4
|
+
source_root File.expand_path('../templates', __FILE__)
|
5
|
+
|
6
|
+
# def create_migration_file
|
7
|
+
# set_local_assigns!
|
8
|
+
# migration_template "migration.rb", "db/migrate/#{file_name}.rb"
|
9
|
+
# end
|
10
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
class <%= migration_class_name %> < ActiveRecord::MigrationWithoutTransaction
|
2
|
+
def up
|
3
|
+
schema = 'accounting'
|
4
|
+
['base_', 'small_', 'micro_', 'independent_', 'nonprofit_'].each do |table_prefix|
|
5
|
+
# Code to run on "accounting" schema
|
6
|
+
|
7
|
+
end
|
8
|
+
|
9
|
+
migrate_user_templates do |schema, table_prefix, ut|
|
10
|
+
# Code to run on user templates' schemas
|
11
|
+
|
12
|
+
# IF CHANGING TABLE we need to keep low cpu usage on DB
|
13
|
+
sleep 0.050
|
14
|
+
end
|
15
|
+
|
16
|
+
migrate_fiscal_years do |schema, table_prefix, fy|
|
17
|
+
# Code to run on fiscal years' schemas
|
18
|
+
|
19
|
+
# IF CHANGING TABLE we need to keep low cpu usage on DB
|
20
|
+
sleep 0.050
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def down
|
25
|
+
schema = 'accounting'
|
26
|
+
['base_', 'small_', 'micro_', 'independent_', 'nonprofit_'].each do |table_prefix|
|
27
|
+
# Code to run on "accounting" schema
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
rollback_user_templates do |schema, table_prefix, ut|
|
32
|
+
# Code to run on user templates' schemas
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
rollback_fiscal_years do |schema, table_prefix, fy|
|
37
|
+
# Code to run on fiscal years' schemas
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'rails/generators/active_record/migration/migration_generator'
|
2
|
+
|
3
|
+
class AccountingPayrollMigrationGenerator < ActiveRecord::Generators::MigrationGenerator
|
4
|
+
source_root File.expand_path('../templates', __FILE__)
|
5
|
+
|
6
|
+
# def create_migration_file
|
7
|
+
# set_local_assigns!
|
8
|
+
# migration_template "migration.rb", "db/migrate/#{file_name}.rb"
|
9
|
+
# end
|
10
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
class <%= migration_class_name %> < ActiveRecord::MigrationWithoutTransaction
|
2
|
+
def up
|
3
|
+
migrate_fiscal_years do |schema, table_prefix, fy, company_id|
|
4
|
+
result = execute %Q[ SELECT sharded_schema FROM sharding.get_sharded_schema_name(#{company_id}); ]
|
5
|
+
sharded_schema = result.first["sharded_schema"]
|
6
|
+
execute <<-SQL
|
7
|
+
DO $BODY$
|
8
|
+
DECLARE
|
9
|
+
BEGIN
|
10
|
+
|
11
|
+
WITH _needs_update AS (
|
12
|
+
SELECT tcda.id,
|
13
|
+
accounting.get_account_best_match('#{schema}','#{table_prefix}',COALESCE(tcda.social_organ_account::text,po.social_organ_account,pi.social_organ_account)) AS social_organ_account,
|
14
|
+
accounting.get_account_best_match('#{schema}','#{table_prefix}',COALESCE(tcda.employee_account::text,po.employee_account,pi.employee_account)) AS employee_account
|
15
|
+
FROM accounting.transaction_suggestions_categories tc
|
16
|
+
JOIN public.payroll_items pi ON pi.type = tc.id
|
17
|
+
LEFT JOIN public.payroll_item_overrides po ON (po.company_id = #{company_id} AND po.payroll_item_id = pi.id)
|
18
|
+
JOIN #{schema}.#{table_prefix}transaction_suggestions_default_accounts tcda ON (tcda.category_id = pi.type AND tcda.item_id = pi.id)
|
19
|
+
WHERE ( pi.company_id = #{company_id} OR pi.company_id IS NULL )
|
20
|
+
AND (tcda.social_organ_account IS NULL OR tcda.employee_account IS NULL)
|
21
|
+
)
|
22
|
+
UPDATE #{schema}.#{table_prefix}transaction_suggestions_default_accounts
|
23
|
+
SET social_organ_account = _needs_update.social_organ_account,
|
24
|
+
employee_account = _needs_update.employee_account
|
25
|
+
FROM _needs_update
|
26
|
+
WHERE #{schema}.#{table_prefix}transaction_suggestions_default_accounts.id = _needs_update.id
|
27
|
+
AND (_needs_update.social_organ_account IS NOT NULL OR _needs_update.employee_account IS NOT NULL);
|
28
|
+
|
29
|
+
INSERT INTO #{schema}.#{table_prefix}transaction_suggestions_default_accounts
|
30
|
+
(category_id, item_id, social_organ_account, employee_account, use_employee_account)
|
31
|
+
SELECT pi.type AS category_id,
|
32
|
+
pi.id AS item_id,
|
33
|
+
accounting.get_account_best_match('#{schema}','#{table_prefix}',COALESCE(po.social_organ_account,pi.social_organ_account)) AS social_organ_account,
|
34
|
+
accounting.get_account_best_match('#{schema}','#{table_prefix}',COALESCE(po.employee_account,pi.employee_account)) AS employee_account,
|
35
|
+
COALESCE(po.use_employee_account,pi.use_employee_account) AS use_employee_account
|
36
|
+
FROM accounting.transaction_suggestions_categories tc
|
37
|
+
JOIN public.payroll_items pi ON pi.type = tc.id
|
38
|
+
LEFT JOIN public.payroll_item_overrides po ON (po.company_id = #{company_id} AND po.payroll_item_id = pi.id)
|
39
|
+
LEFT JOIN #{schema}.#{table_prefix}transaction_suggestions_default_accounts tcda ON (tcda.category_id = pi.type AND tcda.item_id = pi.id)
|
40
|
+
WHERE ( pi.company_id = #{company_id} OR pi.company_id IS NULL )
|
41
|
+
AND tcda IS NULL
|
42
|
+
ORDER BY pi.id;
|
43
|
+
|
44
|
+
INSERT INTO #{schema}.#{table_prefix}transaction_suggestions_default_accounts
|
45
|
+
(category_id, item_id, social_organ_account, employee_account, use_employee_account)
|
46
|
+
SELECT CASE
|
47
|
+
WHEN paa.category = 'Taxes' THEN 'Payroll::Tax'
|
48
|
+
WHEN paa.category = 'Third parties' THEN 'Payroll::ThirdParty'
|
49
|
+
END AS category_id,
|
50
|
+
paa.id AS item_id,
|
51
|
+
accounting.get_account_best_match('#{schema}','#{table_prefix}',paa.social_organ_account) AS social_organ_account,
|
52
|
+
accounting.get_account_best_match('#{schema}','#{table_prefix}',paa.employee_account) AS employee_account,
|
53
|
+
paa.use_employee_account
|
54
|
+
FROM #{sharded_schema}.payroll_accounting_accounts paa
|
55
|
+
LEFT JOIN #{schema}.#{table_prefix}transaction_suggestions_default_accounts tcda ON (tcda.category_id IN ('Payroll::Tax','Payroll::ThirdParty') AND tcda.item_id = paa.id)
|
56
|
+
WHERE paa.company_id = #{company_id}
|
57
|
+
AND paa.category IN ('Taxes', 'Third parties')
|
58
|
+
AND paa.code NOT IN ('BBNK','BCSH')
|
59
|
+
AND tcda IS NULL
|
60
|
+
ORDER BY paa.id;
|
61
|
+
END;
|
62
|
+
$BODY$ LANGUAGE 'plpgsql';
|
63
|
+
SQL
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def down
|
68
|
+
puts "Not reverting"
|
69
|
+
rollback_fiscal_years {}
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'rails/generators/active_record/migration/migration_generator'
|
2
|
+
|
3
|
+
class ShardedMigrationGenerator < ActiveRecord::Generators::MigrationGenerator
|
4
|
+
source_root File.expand_path('../templates', __FILE__)
|
5
|
+
|
6
|
+
# def create_migration_file
|
7
|
+
# set_local_assigns!
|
8
|
+
# migration_template "migration.rb", "db/migrate/#{file_name}.rb"
|
9
|
+
# end
|
10
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
class <%= migration_class_name %> < ActiveRecord::MigrationWithoutTransaction
|
2
|
+
def up
|
3
|
+
migrate_companies do |schema_name, company_id|
|
4
|
+
case schema_name
|
5
|
+
when 'public'
|
6
|
+
# Code to run on "public" schema
|
7
|
+
|
8
|
+
when 'sharded'
|
9
|
+
# Code to run on "sharded" schema
|
10
|
+
# STUCTURE CHANGES TO TABLES IN THIS SCHEMA MUST ONLY RUN IF ADDING OR REMOVING COLUMNS, NOTHING ELSE!
|
11
|
+
|
12
|
+
else
|
13
|
+
# Code to run on sharded companies' schemas
|
14
|
+
|
15
|
+
end
|
16
|
+
# IF CHANGING TABLE we need to keep low cpu usage on DB
|
17
|
+
sleep 0.100
|
18
|
+
end
|
19
|
+
|
20
|
+
# If migration add structural changes on public objects and want run migration
|
21
|
+
# withou a full deploy, please uncomment the next line
|
22
|
+
# invalidate_postgresql_redis_cache!
|
23
|
+
end
|
24
|
+
|
25
|
+
def down
|
26
|
+
rollback_companies do |schema_name, company_id|
|
27
|
+
case schema_name
|
28
|
+
when 'public'
|
29
|
+
# Code to run on "public" schema
|
30
|
+
|
31
|
+
when 'sharded'
|
32
|
+
# Code to run on "sharded" schema
|
33
|
+
# STUCTURE CHANGES TO TABLES IN THIS SCHEMA MUST ONLY RUN IF ADDING OR REMOVING COLUMNS, NOTHING ELSE!
|
34
|
+
|
35
|
+
else
|
36
|
+
# Code to run on sharded companies' schemas
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# If migration add structural changes on public objects and want run migration
|
42
|
+
# withou a full deploy, please uncomment the next line
|
43
|
+
# invalidate_postgresql_redis_cache!
|
44
|
+
end
|
45
|
+
end
|