dorsale 3.14.9 → 3.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +20 -0
- data/app/assets/javascripts/dorsale/dependencies.coffee +1 -1
- data/app/assets/javascripts/dorsale/engines/billing_machine.coffee.erb +14 -0
- data/app/assets/stylesheets/dorsale/engines/billing_machine.sass +4 -1
- data/app/controllers/dorsale/billing_machine/invoices_controller.rb +14 -9
- data/app/controllers/dorsale/billing_machine/quotations_controller.rb +14 -9
- data/app/controllers/dorsale/customer_vault/events_controller.rb +0 -2
- data/app/controllers/dorsale/flyboy/task_comments_controller.rb +2 -2
- data/app/mailers/dorsale/flyboy/task_mailer.rb +2 -2
- data/app/models/dorsale/billing_machine/invoice.rb +2 -4
- data/app/models/dorsale/billing_machine/invoice_line.rb +1 -1
- data/app/models/dorsale/billing_machine/quotation.rb +1 -2
- data/app/models/dorsale/billing_machine/quotation_line.rb +1 -1
- data/app/models/dorsale/customer_vault/corporation.rb +11 -2
- data/app/models/dorsale/customer_vault/individual.rb +4 -2
- data/app/models/dorsale/customer_vault/person.rb +7 -7
- data/app/pdfs/dorsale/billing_machine/invoice_single_vat_pdf.rb +2 -2
- data/app/policies/dorsale/application_policy.rb +1 -0
- data/app/services/dorsale/billing_machine/invoice/copy.rb +1 -0
- data/app/services/dorsale/billing_machine/pdf_file_generator.rb +1 -7
- data/app/services/dorsale/billing_machine/quotation/copy.rb +1 -0
- data/app/services/dorsale/billing_machine/quotation/to_invoice.rb +1 -0
- data/app/services/dorsale/expense_gun/expense/copy.rb +1 -0
- data/app/services/dorsale/flyboy/task/copy.rb +1 -0
- data/app/services/dorsale/flyboy/task/snoozer.rb +1 -0
- data/app/services/dorsale/tag_list_for_model.rb +1 -0
- data/app/views/dorsale/billing_machine/commons/_form.html.slim +2 -1
- data/app/views/dorsale/billing_machine/commons/_line_fields.html.slim +4 -0
- data/app/views/dorsale/billing_machine/invoices/show.pdf.ruby +1 -1
- data/app/views/dorsale/billing_machine/quotations/show.pdf.ruby +1 -1
- data/app/views/dorsale/flyboy/task_mailer/new_task.html.slim +1 -1
- data/app/views/dorsale/flyboy/task_mailer/term_email.html.slim +1 -1
- data/config/locales/billing_machine.fr.yml +1 -0
- data/db/migrate/20210202100529_billing_machine_add_positions.rb +6 -0
- data/db/migrate/20210311131928_billing_machine_add_missing_unique_indexes.rb +6 -0
- data/features/step_definitions/billing_machine_payment_terms_steps.rb +1 -1
- data/features/step_definitions/billing_machine_quotations_steps.rb +1 -1
- data/features/step_definitions/customer_vault_activity_types_steps.rb +1 -1
- data/features/step_definitions/customer_vault_origins_steps.rb +1 -1
- data/features/step_definitions/customer_vault_people_steps.rb +1 -1
- data/features/step_definitions/customer_vault_search_steps.rb +10 -10
- data/features/step_definitions/expense_gun_categories_steps.rb +1 -1
- data/lib/dorsale/version.rb +1 -1
- data/spec/controllers/dorsale/flyboy/task_comments_controller_spec.rb +2 -2
- data/spec/factories/customer_vault_individuals.rb +13 -13
- data/spec/factories/expense_gun_categories.rb +3 -3
- data/spec/factories/expense_gun_expense_lines.rb +7 -7
- data/spec/factories/expense_gun_expenses.rb +3 -3
- data/spec/pdfs/dorsale/billing_machine/invoice_multiple_vat_pdf_spec.rb +1 -1
- data/spec/pdfs/dorsale/billing_machine/invoice_single_vat_pdf_spec.rb +1 -1
- data/spec/pdfs/dorsale/billing_machine/quotation_multiple_vat_pdf_spec.rb +1 -1
- data/spec/pdfs/dorsale/billing_machine/quotation_single_vat_pdf_spec.rb +1 -1
- data/spec/rails_helper.rb +0 -1
- metadata +5 -21
- data/app/assets/javascripts/url.min.js +0 -1
- data/app/models/dorsale/customer_vault/corporation_data.rb +0 -10
- data/app/models/dorsale/customer_vault/individual_data.rb +0 -3
- data/app/models/dorsale/customer_vault/person_data.rb +0 -17
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: edb8363b4a987b737cfba9c432a65fd5c64fbb72690c51f6ea5da99c195430a6
|
|
4
|
+
data.tar.gz: 9b88ffbea03b8971f2a853c5dfcbe6387670ec7b69d8601d68ab295ba425364c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c84800985f5243887825313437907d6a40d2ab5398e7c78de903d404a9c3d5e1d01e6bed9c7cee4fe57f15af26d0aa0c1950ede73946dd3d3f8c14a7ce20a6e1
|
|
7
|
+
data.tar.gz: 373d7d5e133bcb61443e8defed065177fb6e82fc56bc7424abbb110f3632d51a07a24df569f96d2b336206339a2774d26c206d5b1ff6e6862f6d5b63baa061fb
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
## Next version
|
|
4
4
|
|
|
5
|
+
## 3.17.0
|
|
6
|
+
- Refactor CV models using stores
|
|
7
|
+
- Fix redirect after task comment create
|
|
8
|
+
- Add missing unique indexes on invoices and quotations
|
|
9
|
+
|
|
10
|
+
## 3.16.0
|
|
11
|
+
- Allow to reorder BM lines (require Sorting.js + reimport migrations)
|
|
12
|
+
- Remove unused url.js
|
|
13
|
+
|
|
14
|
+
## 3.15.0
|
|
15
|
+
- Fix Ruby 2.7 warnings
|
|
16
|
+
- Faker 2
|
|
17
|
+
|
|
18
|
+
## 3.14.11
|
|
19
|
+
- Fix BM missing PDFs
|
|
20
|
+
|
|
21
|
+
## 3.14.10
|
|
22
|
+
- Change BillingMachine PDF filenames
|
|
23
|
+
- Fix CustomerVault layout
|
|
24
|
+
|
|
5
25
|
## 3.14.9
|
|
6
26
|
- Create corporation from individual form
|
|
7
27
|
- Quotations: add draft state
|
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
//= require bootstrap
|
|
5
5
|
//= require cocoon
|
|
6
6
|
//= require accounting
|
|
7
|
-
//= require url.min
|
|
8
7
|
//= require select2
|
|
9
8
|
//= require select2_locale_fr
|
|
10
9
|
//= require bootstrap-datepicker/core
|
|
11
10
|
//= require bootstrap-datepicker/locales/bootstrap-datepicker.fr
|
|
12
11
|
//= require Chart.bundle
|
|
13
12
|
//= require chartkick
|
|
13
|
+
//= require Sortable
|
|
14
14
|
//= require agilibox/all
|
|
@@ -77,6 +77,10 @@ BillingMachine.formatInputs = ->
|
|
|
77
77
|
formatted_number = BillingMachine.num2str BillingMachine.str2num $(this).val()
|
|
78
78
|
$(this).val formatted_number
|
|
79
79
|
|
|
80
|
+
BillingMachine.updatePositions = ->
|
|
81
|
+
i = 0
|
|
82
|
+
$("#billing_machine-form input[name*=position]").map -> this.value = (i = i + 1)
|
|
83
|
+
|
|
80
84
|
# Empty number inputs on focus if value is 0
|
|
81
85
|
$(document).on "focus", "#billing_machine-form input.number", ->
|
|
82
86
|
$(this).val("") if BillingMachine.str2num($(this).val()) == 0
|
|
@@ -96,6 +100,7 @@ $(document).on "click", "#billing_machine-form a.delete", (e) ->
|
|
|
96
100
|
$(document).on "turbolinks:load cocoon:after-insert", ->
|
|
97
101
|
BillingMachine.formatInputs()
|
|
98
102
|
BillingMachine.updateTotals()
|
|
103
|
+
BillingMachine.updatePositions()
|
|
99
104
|
|
|
100
105
|
# Fix Cocoon bug
|
|
101
106
|
$("#billing_machine-form .line textarea").map ->
|
|
@@ -106,3 +111,12 @@ $(document).on "keyup", "#billing_machine-form input.number", ->
|
|
|
106
111
|
|
|
107
112
|
$(document).on "blur", "#billing_machine-form input.number", ->
|
|
108
113
|
BillingMachine.formatInputs()
|
|
114
|
+
|
|
115
|
+
$(document).on "turbolinks:load", ->
|
|
116
|
+
$("#billing_machine-form tbody").map ->
|
|
117
|
+
container = this
|
|
118
|
+
|
|
119
|
+
new Sortable container,
|
|
120
|
+
handle: ".handle"
|
|
121
|
+
animation: 150
|
|
122
|
+
onSort: -> BillingMachine.updatePositions()
|
|
@@ -157,15 +157,20 @@ class Dorsale::BillingMachine::InvoicesController < ::Dorsale::BillingMachine::A
|
|
|
157
157
|
:advance,
|
|
158
158
|
:due_date,
|
|
159
159
|
:comments,
|
|
160
|
-
:lines_attributes =>
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
160
|
+
:lines_attributes => line_permitted_params,
|
|
161
|
+
]
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def line_permitted_params
|
|
165
|
+
[
|
|
166
|
+
:_destroy,
|
|
167
|
+
:id,
|
|
168
|
+
:label,
|
|
169
|
+
:quantity,
|
|
170
|
+
:unit,
|
|
171
|
+
:unit_price,
|
|
172
|
+
:vat_rate,
|
|
173
|
+
:position,
|
|
169
174
|
]
|
|
170
175
|
end
|
|
171
176
|
|
|
@@ -165,15 +165,20 @@ class Dorsale::BillingMachine::QuotationsController < ::Dorsale::BillingMachine:
|
|
|
165
165
|
:comments,
|
|
166
166
|
:vat_rate,
|
|
167
167
|
:commercial_discount,
|
|
168
|
-
:lines_attributes =>
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
168
|
+
:lines_attributes => line_permitted_params,
|
|
169
|
+
]
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def line_permitted_params
|
|
173
|
+
[
|
|
174
|
+
:_destroy,
|
|
175
|
+
:id,
|
|
176
|
+
:label,
|
|
177
|
+
:quantity,
|
|
178
|
+
:unit,
|
|
179
|
+
:unit_price,
|
|
180
|
+
:vat_rate,
|
|
181
|
+
:position,
|
|
177
182
|
]
|
|
178
183
|
end
|
|
179
184
|
|
|
@@ -19,9 +19,9 @@ class Dorsale::Flyboy::TaskCommentsController < ::Dorsale::Flyboy::ApplicationCo
|
|
|
19
19
|
|
|
20
20
|
def back_url
|
|
21
21
|
task_path = flyboy_task_path(@task)
|
|
22
|
-
back_url = super
|
|
22
|
+
back_url = super.to_s
|
|
23
23
|
|
|
24
|
-
if back_url.
|
|
24
|
+
if back_url == task_path || back_url.start_with?(task_path + "?")
|
|
25
25
|
back_url
|
|
26
26
|
else
|
|
27
27
|
task_path
|
|
@@ -11,7 +11,7 @@ class Dorsale::Flyboy::TaskMailer < ::Dorsale::ApplicationMailer
|
|
|
11
11
|
|
|
12
12
|
mail(
|
|
13
13
|
:to => task.owner.email,
|
|
14
|
-
:subject => t("task_mailer.new_task.subject",
|
|
14
|
+
:subject => t("task_mailer.new_task.subject", **@locals),
|
|
15
15
|
)
|
|
16
16
|
end
|
|
17
17
|
|
|
@@ -26,7 +26,7 @@ class Dorsale::Flyboy::TaskMailer < ::Dorsale::ApplicationMailer
|
|
|
26
26
|
|
|
27
27
|
mail(
|
|
28
28
|
:to => task.owner.email,
|
|
29
|
-
:subject => t("task_mailer.term_email.subject",
|
|
29
|
+
:subject => t("task_mailer.term_email.subject", **@locals),
|
|
30
30
|
)
|
|
31
31
|
end
|
|
32
32
|
end
|
|
@@ -22,6 +22,8 @@ class Dorsale::BillingMachine::Invoice < ::Dorsale::ApplicationRecord
|
|
|
22
22
|
:invoice
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
+
after_initialize :assign_default_dates
|
|
26
|
+
before_save :update_totals
|
|
25
27
|
before_create :assign_unique_index
|
|
26
28
|
before_create :assign_tracking_id
|
|
27
29
|
|
|
@@ -43,15 +45,11 @@ class Dorsale::BillingMachine::Invoice < ::Dorsale::ApplicationRecord
|
|
|
43
45
|
assign_default :paid, false
|
|
44
46
|
end
|
|
45
47
|
|
|
46
|
-
after_initialize :assign_default_dates
|
|
47
|
-
|
|
48
48
|
def assign_default_dates
|
|
49
49
|
assign_default :date, Date.current
|
|
50
50
|
assign_default :due_date, Date.current + 30.days
|
|
51
51
|
end
|
|
52
52
|
|
|
53
|
-
before_save :update_totals
|
|
54
|
-
|
|
55
53
|
def update_totals
|
|
56
54
|
assign_default_values
|
|
57
55
|
lines.each(&:update_total)
|
|
@@ -33,6 +33,7 @@ class Dorsale::BillingMachine::Quotation < ::Dorsale::ApplicationRecord
|
|
|
33
33
|
:quotation
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
+
before_save :update_totals
|
|
36
37
|
before_create :assign_unique_index
|
|
37
38
|
before_create :assign_tracking_id
|
|
38
39
|
|
|
@@ -55,8 +56,6 @@ class Dorsale::BillingMachine::Quotation < ::Dorsale::ApplicationRecord
|
|
|
55
56
|
assign_default :total_excluding_taxes, 0
|
|
56
57
|
end
|
|
57
58
|
|
|
58
|
-
before_save :update_totals
|
|
59
|
-
|
|
60
59
|
def update_totals
|
|
61
60
|
assign_default_values
|
|
62
61
|
lines.each(&:update_total)
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
class Dorsale::CustomerVault::Corporation < Dorsale::CustomerVault::Person
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
data_attributes = %i(
|
|
3
|
+
legal_form
|
|
4
|
+
immatriculation_number
|
|
5
|
+
naf
|
|
6
|
+
european_union_vat_number
|
|
7
|
+
societe_com
|
|
8
|
+
capital
|
|
9
|
+
revenue
|
|
10
|
+
number_of_employees
|
|
11
|
+
)
|
|
12
|
+
store :data, accessors: data_attributes, coder: JSON
|
|
4
13
|
|
|
5
14
|
validates :corporation_name, presence: true
|
|
6
15
|
has_many :individuals, dependent: :nullify
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
class Dorsale::CustomerVault::Individual < Dorsale::CustomerVault::Person
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
data_attributes = %i(
|
|
3
|
+
title
|
|
4
|
+
)
|
|
5
|
+
store :data, accessors: data_attributes, coder: JSON
|
|
4
6
|
|
|
5
7
|
validates :first_name, presence: true
|
|
6
8
|
validates :last_name, presence: true
|
|
@@ -9,8 +9,6 @@ class Dorsale::CustomerVault::Person < ::Dorsale::ApplicationRecord
|
|
|
9
9
|
Dorsale::CustomerVault::PersonPolicy
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
after_initialize :verify_class
|
|
13
|
-
|
|
14
12
|
def verify_class
|
|
15
13
|
if self.class == ::Dorsale::CustomerVault::Person
|
|
16
14
|
# self.abstract_class does not work with STI
|
|
@@ -30,6 +28,13 @@ class Dorsale::CustomerVault::Person < ::Dorsale::ApplicationRecord
|
|
|
30
28
|
belongs_to :activity_type, class_name: "Dorsale::CustomerVault::ActivityType"
|
|
31
29
|
belongs_to :origin, class_name: "Dorsale::CustomerVault::Origin"
|
|
32
30
|
|
|
31
|
+
validate :validate_taken_emails
|
|
32
|
+
|
|
33
|
+
after_initialize :verify_class
|
|
34
|
+
after_initialize :build_address, if: proc { new_record? && address.nil? }
|
|
35
|
+
|
|
36
|
+
before_validation :build_address, if: proc { address.nil? }
|
|
37
|
+
|
|
33
38
|
after_destroy :destroy_links
|
|
34
39
|
|
|
35
40
|
default_scope -> {
|
|
@@ -50,9 +55,6 @@ class Dorsale::CustomerVault::Person < ::Dorsale::ApplicationRecord
|
|
|
50
55
|
|
|
51
56
|
scope :having_email, -> (email) { where("email = :e OR :e = ANY (secondary_emails)", e: email) }
|
|
52
57
|
|
|
53
|
-
after_initialize :build_address, if: proc { new_record? && address.nil? }
|
|
54
|
-
before_validation :build_address, if: proc { address.nil? }
|
|
55
|
-
|
|
56
58
|
def taken_emails
|
|
57
59
|
taken_emails = {}
|
|
58
60
|
([email] + secondary_emails).select(&:present?).each do |e|
|
|
@@ -62,8 +64,6 @@ class Dorsale::CustomerVault::Person < ::Dorsale::ApplicationRecord
|
|
|
62
64
|
taken_emails
|
|
63
65
|
end
|
|
64
66
|
|
|
65
|
-
validate :validate_taken_emails
|
|
66
|
-
|
|
67
67
|
def validate_taken_emails
|
|
68
68
|
return if taken_emails.empty?
|
|
69
69
|
|
|
@@ -177,11 +177,11 @@ class Dorsale::BillingMachine::InvoiceSingleVatPdf < Dorsale::ApplicationPdf
|
|
|
177
177
|
end
|
|
178
178
|
|
|
179
179
|
def has_advance
|
|
180
|
-
main_document.try(:advance) && main_document.advance != 0.0
|
|
180
|
+
main_document.try(:advance) && main_document.advance.to_d != 0.0.to_d
|
|
181
181
|
end
|
|
182
182
|
|
|
183
183
|
def has_discount
|
|
184
|
-
main_document.try(:commercial_discount) && main_document.commercial_discount != 0.0
|
|
184
|
+
main_document.try(:commercial_discount) && main_document.commercial_discount.to_d != 0.0.to_d
|
|
185
185
|
end
|
|
186
186
|
|
|
187
187
|
def build_table
|
|
@@ -2,14 +2,8 @@ class Dorsale::BillingMachine::PdfFileGenerator < Dorsale::Service
|
|
|
2
2
|
attr_reader :document
|
|
3
3
|
|
|
4
4
|
def initialize(document)
|
|
5
|
+
super()
|
|
5
6
|
@document = document
|
|
6
|
-
|
|
7
|
-
# I have no idea why I need to do that,
|
|
8
|
-
# if I don't do that, CarrierWare do not stores the file.
|
|
9
|
-
# The reload() method don't work either.
|
|
10
|
-
# The problem appears only on server, not in console.
|
|
11
|
-
# I think CarrierWave do not work anymore after first save.
|
|
12
|
-
@document = document.class.find(document.id) if document.persisted?
|
|
13
7
|
end
|
|
14
8
|
|
|
15
9
|
def call
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
table#lines-table
|
|
22
22
|
thead
|
|
23
23
|
tr
|
|
24
|
+
th.position
|
|
24
25
|
th.actions
|
|
25
26
|
th.line-label = Dorsale::BillingMachine::InvoiceLine.t(:label)
|
|
26
27
|
th.line-quantity = Dorsale::BillingMachine::InvoiceLine.t(:quantity)
|
|
@@ -32,7 +33,7 @@
|
|
|
32
33
|
|
|
33
34
|
tbody
|
|
34
35
|
= f.simple_fields_for :lines do |lf|
|
|
35
|
-
= render "dorsale/billing_machine/
|
|
36
|
+
= render "dorsale/billing_machine/#{document.document_type}s/line_fields", f: lf
|
|
36
37
|
|
|
37
38
|
.row
|
|
38
39
|
.col-sm-6
|
|
@@ -1 +1 @@
|
|
|
1
|
-
p == lf2br t("task_mailer.new_task.body",
|
|
1
|
+
p == lf2br t("task_mailer.new_task.body", **@locals)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
p == lf2br t("task_mailer.term_email.body",
|
|
1
|
+
p == lf2br t("task_mailer.term_email.body", **@locals)
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
class BillingMachineAddPositions < ActiveRecord::Migration[6.0]
|
|
2
|
+
def change
|
|
3
|
+
add_column :dorsale_billing_machine_invoice_lines, :position, :integer, null: false, default: 0
|
|
4
|
+
add_column :dorsale_billing_machine_quotation_lines, :position, :integer, null: false, default: 0
|
|
5
|
+
end
|
|
6
|
+
end
|
|
@@ -28,7 +28,7 @@ When(/^the user edits the payment_term$/) do
|
|
|
28
28
|
find(".link_update").click
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
-
Then(/^the current payment_term's label should be pre
|
|
31
|
+
Then(/^the current payment_term's label should be pre-filled$/) do
|
|
32
32
|
expect(page).to have_field("billing_machine_payment_term_label", with: @payment_term.label)
|
|
33
33
|
end
|
|
34
34
|
|
|
@@ -58,7 +58,7 @@ When(/^the quotation line shows the right date$/) do
|
|
|
58
58
|
expect(page).to have_selector ".date", text: I18n.l(@quotation.date)
|
|
59
59
|
end
|
|
60
60
|
|
|
61
|
-
When(/^the quotation line shows the right traking
|
|
61
|
+
When(/^the quotation line shows the right traking-id$/) do
|
|
62
62
|
expect(page).to have_selector ".tracking_id", text: @quotation.tracking_id
|
|
63
63
|
end
|
|
64
64
|
|
|
@@ -28,7 +28,7 @@ When(/^I edit the activity type$/) do
|
|
|
28
28
|
find(".link_update").click
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
-
Then(/^the current activity type's name should be pre
|
|
31
|
+
Then(/^the current activity type's name should be pre-filled$/) do
|
|
32
32
|
expect(page).to have_field("activity_type_name", with: @activity_type.name)
|
|
33
33
|
end
|
|
34
34
|
|
|
@@ -28,7 +28,7 @@ When(/^I edit the origin$/) do
|
|
|
28
28
|
find(".link_update").click
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
-
Then(/^the current origin's name should be pre
|
|
31
|
+
Then(/^the current origin's name should be pre-filled$/) do
|
|
32
32
|
expect(page).to have_field("origin_name", with: @origin.name)
|
|
33
33
|
end
|
|
34
34
|
|
|
@@ -7,7 +7,7 @@ Then(/^the file is downloaded$/) do
|
|
|
7
7
|
end
|
|
8
8
|
|
|
9
9
|
Given(/^a very long comment on this person$/) do
|
|
10
|
-
text = Faker::Lorem.paragraph(30)
|
|
10
|
+
text = Faker::Lorem.paragraph(sentence_count: 30)
|
|
11
11
|
@comment = create(:customer_vault_event_comment, person: @person, text: text)
|
|
12
12
|
end
|
|
13
13
|
|
|
@@ -1,48 +1,48 @@
|
|
|
1
|
-
|
|
1
|
+
When(/^he go to the people list$/) do
|
|
2
2
|
visit dorsale.customer_vault_people_path
|
|
3
3
|
end
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Given(/^existing individuals$/) do
|
|
6
6
|
@individual1 = create(:customer_vault_individual, first_name: "Jean", last_name: "DUPONT")
|
|
7
7
|
@individual2 = create(:customer_vault_individual, first_name: "Laurent", last_name: "DURAND")
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Given(/^existing corporations$/) do
|
|
11
11
|
@corporation1 = create(:customer_vault_corporation, name: "aaa", email: "contact@aaa.com")
|
|
12
12
|
@corporation2 = create(:customer_vault_corporation, name: "zzz", email: "contact@zzz.com")
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
When(/^he search an individual by first name$/) do
|
|
16
16
|
fill_in "q", with: "Jean"
|
|
17
17
|
find(".search-submit").click
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
Then(/^this individual appear in search results$/) do
|
|
21
21
|
expect(page).to have_content "Jean"
|
|
22
22
|
expect(page).to have_content "DUPONT"
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
Then(/^other individuals do not appear in search results$/) do
|
|
26
26
|
expect(page).to have_no_content "Laurent"
|
|
27
27
|
expect(page).to have_no_content "DURAND"
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
When(/^he search an individual by last name$/) do
|
|
31
31
|
fill_in "q", with: "DUPONT"
|
|
32
32
|
find(".search-submit").click
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
When(/^he search a corporation by name$/) do
|
|
36
36
|
fill_in "q", with: "aaa"
|
|
37
37
|
find(".search-submit").click
|
|
38
38
|
end
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
Then(/^this corporation appear in search results$/) do
|
|
41
41
|
expect(page).to have_content "aaa"
|
|
42
42
|
expect(page).to have_content "contact@aaa.com"
|
|
43
43
|
end
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
Then(/^other corporations do not appear in search results$/) do
|
|
46
46
|
expect(page).to have_no_content "zzz"
|
|
47
47
|
expect(page).to have_no_content "contact@zzz.com"
|
|
48
48
|
end
|
|
@@ -28,7 +28,7 @@ When(/^I edit the expense category$/) do
|
|
|
28
28
|
find(".link_update").click
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
-
Then(/^the current expense category's label should be pre
|
|
31
|
+
Then(/^the current expense category's label should be pre-filled$/) do
|
|
32
32
|
expect(page).to have_field("category_name", with: @category.name)
|
|
33
33
|
end
|
|
34
34
|
|
data/lib/dorsale/version.rb
CHANGED
|
@@ -18,7 +18,7 @@ describe Dorsale::Flyboy::TaskCommentsController, type: :controller do
|
|
|
18
18
|
expect(assigns(:task_comment).persisted?).to be true
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
it "should redirect to referrer if referrer is task" do
|
|
21
|
+
it "should redirect to referrer if referrer is task show" do
|
|
22
22
|
url = flyboy_task_path(task) + "?sort=xxx"
|
|
23
23
|
request.env["HTTP_REFERER"] = url
|
|
24
24
|
post :create, params: valid_params
|
|
@@ -26,7 +26,7 @@ describe Dorsale::Flyboy::TaskCommentsController, type: :controller do
|
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
it "should redirect to task if referrer is not task" do
|
|
29
|
-
url = "/
|
|
29
|
+
url = flyboy_task_path(task) + "/some-action"
|
|
30
30
|
request.env["HTTP_REFERER"] = url
|
|
31
31
|
post :create, params: valid_params
|
|
32
32
|
expect(response).to redirect_to flyboy_task_path(task)
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
FactoryBot.define do
|
|
2
2
|
factory :customer_vault_individual, class: ::Dorsale::CustomerVault::Individual do
|
|
3
|
-
origin { create(:customer_vault_origin)
|
|
4
|
-
first_name { Faker::Name.first_name
|
|
5
|
-
last_name { Faker::Name.last_name
|
|
6
|
-
short_name { "SN"
|
|
7
|
-
email { Faker::Internet.email(
|
|
8
|
-
title { "Individual-Title"
|
|
9
|
-
twitter { "#{first_name}#{last_name}"
|
|
10
|
-
www { Faker::Internet.url
|
|
11
|
-
context { "Individual-Context"
|
|
12
|
-
phone { "01 23 xx xx xx"
|
|
13
|
-
fax { "09 xx xx xx xx"
|
|
14
|
-
mobile { "06 xx xx xx xx"
|
|
15
|
-
address { build(:dorsale_address)
|
|
3
|
+
origin { create(:customer_vault_origin) }
|
|
4
|
+
first_name { Faker::Name.first_name }
|
|
5
|
+
last_name { Faker::Name.last_name }
|
|
6
|
+
short_name { "SN" }
|
|
7
|
+
email { Faker::Internet.email(name: name) }
|
|
8
|
+
title { "Individual-Title" }
|
|
9
|
+
twitter { "#{first_name}#{last_name}" }
|
|
10
|
+
www { Faker::Internet.url }
|
|
11
|
+
context { "Individual-Context" }
|
|
12
|
+
phone { "01 23 xx xx xx" }
|
|
13
|
+
fax { "09 xx xx xx xx" }
|
|
14
|
+
mobile { "06 xx xx xx xx" }
|
|
15
|
+
address { build(:dorsale_address) }
|
|
16
16
|
end
|
|
17
17
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
FactoryBot.define do
|
|
2
2
|
factory :expense_gun_category, class: ::Dorsale::ExpenseGun::Category do
|
|
3
|
-
name { Faker::Lorem.word
|
|
4
|
-
code { Faker::Number.number(4) }
|
|
5
|
-
vat_deductible { [true, false].sample
|
|
3
|
+
name { Faker::Lorem.word }
|
|
4
|
+
code { Faker::Number.number(digits: 4) }
|
|
5
|
+
vat_deductible { [true, false].sample }
|
|
6
6
|
end
|
|
7
7
|
end
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
FactoryBot.define do
|
|
2
2
|
factory :expense_gun_expense_line, class: ::Dorsale::ExpenseGun::ExpenseLine do
|
|
3
|
-
expense { build(:expense_gun_expense)
|
|
4
|
-
name { Faker::Lorem.sentence(3)
|
|
5
|
-
category { build(:expense_gun_category)
|
|
6
|
-
date { Faker::Date.backward(30)
|
|
7
|
-
total_all_taxes { rand(100..1000)
|
|
8
|
-
vat { rand(1..(total_all_taxes/5))
|
|
9
|
-
company_part { [25, 50, 75, 100].sample
|
|
3
|
+
expense { build(:expense_gun_expense) }
|
|
4
|
+
name { Faker::Lorem.sentence(word_count: 3) }
|
|
5
|
+
category { build(:expense_gun_category) }
|
|
6
|
+
date { Faker::Date.backward(days: 30) }
|
|
7
|
+
total_all_taxes { rand(100..1000) }
|
|
8
|
+
vat { rand(1..(total_all_taxes/5)) }
|
|
9
|
+
company_part { [25, 50, 75, 100].sample }
|
|
10
10
|
end
|
|
11
11
|
end
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
FactoryBot.define do
|
|
2
2
|
factory :expense_gun_expense, class: ::Dorsale::ExpenseGun::Expense do
|
|
3
|
-
name { Faker::Lorem.sentence(3) }
|
|
4
|
-
date { Date.current
|
|
5
|
-
user { create(:user)
|
|
3
|
+
name { Faker::Lorem.sentence(word_count: 3) }
|
|
4
|
+
date { Date.current }
|
|
5
|
+
user { create(:user) }
|
|
6
6
|
|
|
7
7
|
after(:create) { |expense|
|
|
8
8
|
rand(2..5).times {
|
|
@@ -23,7 +23,7 @@ describe ::Dorsale::BillingMachine::InvoiceMultipleVatPdf, pdfs: true do
|
|
|
23
23
|
|
|
24
24
|
let(:content) {
|
|
25
25
|
generate!
|
|
26
|
-
|
|
26
|
+
PDF::Reader.new(invoice.pdf_file.path).pages.map(&:text).join("\n")
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
it "should not display global vat rate" do
|
|
@@ -23,7 +23,7 @@ describe ::Dorsale::BillingMachine::InvoiceSingleVatPdf, pdfs: true do
|
|
|
23
23
|
|
|
24
24
|
let(:content) {
|
|
25
25
|
generate!
|
|
26
|
-
|
|
26
|
+
PDF::Reader.new(invoice.pdf_file.path).pages.map(&:text).join("\n")
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
it "should display global vat rate" do
|
|
@@ -23,7 +23,7 @@ describe ::Dorsale::BillingMachine::QuotationMultipleVatPdf, pdfs: true do
|
|
|
23
23
|
|
|
24
24
|
let(:content) {
|
|
25
25
|
generate!
|
|
26
|
-
|
|
26
|
+
PDF::Reader.new(quotation.pdf_file.path).pages.map(&:text).join("\n")
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
it "should not display global vat rate" do
|
|
@@ -23,7 +23,7 @@ describe ::Dorsale::BillingMachine::QuotationSingleVatPdf, pdfs: true do
|
|
|
23
23
|
|
|
24
24
|
let(:content) {
|
|
25
25
|
generate!
|
|
26
|
-
|
|
26
|
+
PDF::Reader.new(quotation.pdf_file.path).pages.map(&:text).join("\n")
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
it "should display global vat rate" do
|
data/spec/rails_helper.rb
CHANGED
|
@@ -4,7 +4,6 @@ require 'spec_helper'
|
|
|
4
4
|
require File.expand_path("../dummy/config/environment", __FILE__)
|
|
5
5
|
require 'rspec/rails'
|
|
6
6
|
require "agilibox/rspec"
|
|
7
|
-
require "yomu"
|
|
8
7
|
# Add additional requires below this line. Rails is not loaded until this point!
|
|
9
8
|
# Requires supporting ruby files with custom matchers and macros, etc,
|
|
10
9
|
# in spec/support/ and its subdirectories.
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dorsale
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.17.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- agilidée
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2021-03-11 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|
|
@@ -50,20 +50,6 @@ dependencies:
|
|
|
50
50
|
- - "<"
|
|
51
51
|
- !ruby/object:Gem::Version
|
|
52
52
|
version: '99'
|
|
53
|
-
- !ruby/object:Gem::Dependency
|
|
54
|
-
name: virtus
|
|
55
|
-
requirement: !ruby/object:Gem::Requirement
|
|
56
|
-
requirements:
|
|
57
|
-
- - "<"
|
|
58
|
-
- !ruby/object:Gem::Version
|
|
59
|
-
version: '99'
|
|
60
|
-
type: :runtime
|
|
61
|
-
prerelease: false
|
|
62
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
63
|
-
requirements:
|
|
64
|
-
- - "<"
|
|
65
|
-
- !ruby/object:Gem::Version
|
|
66
|
-
version: '99'
|
|
67
53
|
- !ruby/object:Gem::Dependency
|
|
68
54
|
name: slim-rails
|
|
69
55
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -468,7 +454,6 @@ files:
|
|
|
468
454
|
- app/assets/javascripts/dorsale/engines/billing_machine.coffee.erb
|
|
469
455
|
- app/assets/javascripts/dorsale/engines/customer_vault.coffee
|
|
470
456
|
- app/assets/javascripts/dorsale/engines/flyboy.coffee
|
|
471
|
-
- app/assets/javascripts/url.min.js
|
|
472
457
|
- app/assets/stylesheets/dorsale/all.sass
|
|
473
458
|
- app/assets/stylesheets/dorsale/common.sass
|
|
474
459
|
- app/assets/stylesheets/dorsale/common/comments.sass
|
|
@@ -550,14 +535,11 @@ files:
|
|
|
550
535
|
- app/models/dorsale/customer_vault.rb
|
|
551
536
|
- app/models/dorsale/customer_vault/activity_type.rb
|
|
552
537
|
- app/models/dorsale/customer_vault/corporation.rb
|
|
553
|
-
- app/models/dorsale/customer_vault/corporation_data.rb
|
|
554
538
|
- app/models/dorsale/customer_vault/event.rb
|
|
555
539
|
- app/models/dorsale/customer_vault/individual.rb
|
|
556
|
-
- app/models/dorsale/customer_vault/individual_data.rb
|
|
557
540
|
- app/models/dorsale/customer_vault/link.rb
|
|
558
541
|
- app/models/dorsale/customer_vault/origin.rb
|
|
559
542
|
- app/models/dorsale/customer_vault/person.rb
|
|
560
|
-
- app/models/dorsale/customer_vault/person_data.rb
|
|
561
543
|
- app/models/dorsale/email.rb
|
|
562
544
|
- app/models/dorsale/expense_gun.rb
|
|
563
545
|
- app/models/dorsale/expense_gun/category.rb
|
|
@@ -835,6 +817,8 @@ files:
|
|
|
835
817
|
- db/migrate/20171023133219_customer_vault_events_add_contact_type.rb
|
|
836
818
|
- db/migrate/20171024075514_customer_vault_contact_type_default_value.rb
|
|
837
819
|
- db/migrate/20171115171425_dorsale_customer_vault_people_add_secondary_emails.rb
|
|
820
|
+
- db/migrate/20210202100529_billing_machine_add_positions.rb
|
|
821
|
+
- db/migrate/20210311131928_billing_machine_add_missing_unique_indexes.rb
|
|
838
822
|
- features/access.feature
|
|
839
823
|
- features/billing_machine_invoices.feature
|
|
840
824
|
- features/billing_machine_multiple_vat.feature
|
|
@@ -989,7 +973,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
989
973
|
- !ruby/object:Gem::Version
|
|
990
974
|
version: '0'
|
|
991
975
|
requirements: []
|
|
992
|
-
rubygems_version: 3.
|
|
976
|
+
rubygems_version: 3.1.4
|
|
993
977
|
signing_key:
|
|
994
978
|
specification_version: 4
|
|
995
979
|
summary: Modular ERP made with Ruby on Rails
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
/*! js-url - v2.3.0 - 2016-03-10 */window.url=function(){function a(){}function b(a){return decodeURIComponent(a.replace(/\+/g," "))}function c(a,b){var c=a.charAt(0),d=b.split(c);return c===a?d:(a=parseInt(a.substring(1),10),d[0>a?d.length+a:a-1])}function d(a,c){for(var d=a.charAt(0),e=c.split("&"),f=[],g={},h=[],i=a.substring(1),j=0,k=e.length;k>j;j++)if(f=e[j].match(/(.*?)=(.*)/),f||(f=[e[j],e[j],""]),""!==f[1].replace(/\s/g,"")){if(f[2]=b(f[2]||""),i===f[1])return f[2];h=f[1].match(/(.*)\[([0-9]+)\]/),h?(g[h[1]]=g[h[1]]||[],g[h[1]][h[2]]=f[2]):g[f[1]]=f[2]}return d===a?g:g[i]}return function(b,e){var f,g={};if("tld?"===b)return a();if(e=e||window.location.toString(),!b)return e;if(b=b.toString(),f=e.match(/^mailto:([^\/].+)/))g.protocol="mailto",g.email=f[1];else{if((f=e.match(/(.*?)\/#\!(.*)/))&&(e=f[1]+f[2]),(f=e.match(/(.*?)#(.*)/))&&(g.hash=f[2],e=f[1]),g.hash&&b.match(/^#/))return d(b,g.hash);if((f=e.match(/(.*?)\?(.*)/))&&(g.query=f[2],e=f[1]),g.query&&b.match(/^\?/))return d(b,g.query);if((f=e.match(/(.*?)\:?\/\/(.*)/))&&(g.protocol=f[1].toLowerCase(),e=f[2]),(f=e.match(/(.*?)(\/.*)/))&&(g.path=f[2],e=f[1]),g.path=(g.path||"").replace(/^([^\/])/,"/$1").replace(/\/$/,""),b.match(/^[\-0-9]+$/)&&(b=b.replace(/^([^\/])/,"/$1")),b.match(/^\//))return c(b,g.path.substring(1));if(f=c("/-1",g.path.substring(1)),f&&(f=f.match(/(.*?)\.(.*)/))&&(g.file=f[0],g.filename=f[1],g.fileext=f[2]),(f=e.match(/(.*)\:([0-9]+)$/))&&(g.port=f[2],e=f[1]),(f=e.match(/(.*?)@(.*)/))&&(g.auth=f[1],e=f[2]),g.auth&&(f=g.auth.match(/(.*)\:(.*)/),g.user=f?f[1]:g.auth,g.pass=f?f[2]:void 0),g.hostname=e.toLowerCase(),"."===b.charAt(0))return c(b,g.hostname);a()&&(f=g.hostname.match(a()),f&&(g.tld=f[3],g.domain=f[2]?f[2]+"."+f[3]:void 0,g.sub=f[1]||void 0)),g.port=g.port||("https"===g.protocol?"443":"80"),g.protocol=g.protocol||("443"===g.port?"https":"http")}return b in g?g[b]:"{}"===b?g:void 0}}(),"undefined"!=typeof jQuery&&jQuery.extend({url:function(a,b){return window.url(a,b)}});
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
class Dorsale::CustomerVault::CorporationData < Dorsale::CustomerVault::PersonData
|
|
2
|
-
attribute :legal_form, String
|
|
3
|
-
attribute :immatriculation_number, String
|
|
4
|
-
attribute :naf, String
|
|
5
|
-
attribute :european_union_vat_number, String
|
|
6
|
-
attribute :societe_com, String
|
|
7
|
-
attribute :capital, Integer
|
|
8
|
-
attribute :revenue, Integer
|
|
9
|
-
attribute :number_of_employees, Integer
|
|
10
|
-
end
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
require "virtus"
|
|
2
|
-
|
|
3
|
-
class Dorsale::CustomerVault::PersonData
|
|
4
|
-
include Virtus.model
|
|
5
|
-
|
|
6
|
-
def self.dump(obj)
|
|
7
|
-
JSON.dump(obj.attributes)
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def self.load(json_string)
|
|
11
|
-
new JSON.parse(json_string.presence || "{}")
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def self.methods_to_delegate
|
|
15
|
-
instance_methods - Dorsale::CustomerVault::PersonData.instance_methods
|
|
16
|
-
end
|
|
17
|
-
end
|