mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-02-19 13:54:25 +01:00
(feat) save the accounting data in DB
Previously, the accounting data were built on demand, extracting the data from the invoices on-the-fly. This is intended to be used only once in a while, so there was no performance issue with that. Now, we want those data to be accessed from the OpenAPI, so building them on-the-fly would be very much intensive and resouces heavy. So we build them each nights using a scheduled worker and save them in the database
This commit is contained in:
parent
514a797b64
commit
af3def0e2e
@ -1,13 +1,14 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# API Controller for resources of type ProfileCustomField
|
||||
# ProfileCustomFields are used to provide admin config user profile custom fields
|
||||
# ProfileCustomFields are fields configured by an admin, added to the user's profile
|
||||
class API::ProfileCustomFieldsController < API::ApiController
|
||||
before_action :authenticate_user!, except: :index
|
||||
before_action :set_profile_custom_field, only: %i[show update destroy]
|
||||
|
||||
def index
|
||||
@profile_custom_fields = ProfileCustomField.all.order('id ASC')
|
||||
@profile_custom_fields = @profile_custom_fields.where(actived: params[:actived]) if params[:actived].present?
|
||||
end
|
||||
|
||||
def show; end
|
||||
|
@ -1,10 +1,11 @@
|
||||
import apiClient from './clients/api-client';
|
||||
import { AxiosResponse } from 'axios';
|
||||
import { ProfileCustomField } from '../models/profile-custom-field';
|
||||
import { ProfileCustomField, ProfileCustomFieldIndexFilters } from '../models/profile-custom-field';
|
||||
import ApiLib from '../lib/api';
|
||||
|
||||
export default class ProfileCustomFieldAPI {
|
||||
static async index (): Promise<Array<ProfileCustomField>> {
|
||||
const res: AxiosResponse<Array<ProfileCustomField>> = await apiClient.get('/api/profile_custom_fields');
|
||||
static async index (filters?: ProfileCustomFieldIndexFilters): Promise<Array<ProfileCustomField>> {
|
||||
const res: AxiosResponse<Array<ProfileCustomField>> = await apiClient.get(`/api/profile_custom_fields${ApiLib.filtersToQuery(filters)}`);
|
||||
return res?.data;
|
||||
}
|
||||
|
||||
|
@ -82,10 +82,9 @@ export const UserProfileForm: React.FC<UserProfileFormProps> = ({ action, size,
|
||||
if (cgu?.custom_asset_file_attributes) setTermsAndConditions(cgu);
|
||||
}).catch(error => onError(error));
|
||||
}
|
||||
ProfileCustomFieldAPI.index().then(data => {
|
||||
const fData = data.filter(f => f.actived);
|
||||
setProfileCustomFields(fData);
|
||||
const userProfileCustomFields = fData.map(f => {
|
||||
ProfileCustomFieldAPI.index({ actived: true }).then(data => {
|
||||
setProfileCustomFields(data);
|
||||
const userProfileCustomFields = data.map(f => {
|
||||
const upcf = user?.invoicing_profile_attributes?.user_profile_custom_fields_attributes?.find(uf => uf.profile_custom_field_id === f.id);
|
||||
return upcf || {
|
||||
value: '',
|
||||
|
@ -1,6 +1,12 @@
|
||||
import { ApiFilter } from './api';
|
||||
|
||||
export interface ProfileCustomField {
|
||||
id: number,
|
||||
label: string,
|
||||
required: boolean,
|
||||
actived: boolean
|
||||
}
|
||||
|
||||
export interface ProfileCustomFieldIndexFilters extends ApiFilter {
|
||||
actived?: boolean
|
||||
}
|
||||
|
8
app/models/accounting_line.rb
Normal file
8
app/models/accounting_line.rb
Normal file
@ -0,0 +1,8 @@
|
||||
# frozen_string_literal: false
|
||||
|
||||
# Stores an accounting datum related to an invoice, matching the French accounting system (PCG).
|
||||
# Accounting data are configured by settings starting with accounting_* and by AdvancedAccounting
|
||||
class AccountingLine < ApplicationRecord
|
||||
belongs_to :invoice
|
||||
belongs_to :invoicing_profile
|
||||
end
|
@ -18,6 +18,8 @@ class Invoice < PaymentDocument
|
||||
has_one :payment_gateway_object, as: :item, dependent: :destroy
|
||||
belongs_to :operator_profile, class_name: 'InvoicingProfile'
|
||||
|
||||
has_many :accounting_lines, dependent: :destroy
|
||||
|
||||
delegate :user, to: :invoicing_profile
|
||||
|
||||
before_create :add_environment
|
||||
|
@ -17,17 +17,20 @@ class InvoicingProfile < ApplicationRecord
|
||||
|
||||
has_many :history_values, dependent: :nullify
|
||||
|
||||
has_many :operated_invoices, foreign_key: :operator_profile_id, class_name: 'Invoice', dependent: :nullify
|
||||
has_many :operated_payment_schedules, foreign_key: :operator_profile_id, class_name: 'PaymentSchedule', dependent: :nullify
|
||||
has_many :operated_invoices, foreign_key: :operator_profile_id, class_name: 'Invoice', dependent: :nullify, inverse_of: :operator_profile
|
||||
has_many :operated_payment_schedules, foreign_key: :operator_profile_id, class_name: 'PaymentSchedule',
|
||||
dependent: :nullify, inverse_of: :operator_profile
|
||||
|
||||
has_many :user_profile_custom_fields
|
||||
has_many :user_profile_custom_fields, dependent: :destroy
|
||||
has_many :profile_custom_fields, through: :user_profile_custom_fields
|
||||
accepts_nested_attributes_for :user_profile_custom_fields, allow_destroy: true
|
||||
|
||||
has_many :accounting_lines, dependent: :destroy
|
||||
|
||||
validates :address, presence: true, if: -> { Setting.get('address_required') }
|
||||
|
||||
def full_name
|
||||
# if first_name or last_name is nil, the empty string will be used as a temporary replacement
|
||||
(first_name || '').humanize.titleize + ' ' + (last_name || '').humanize.titleize
|
||||
"#{(first_name || '').humanize.titleize} #{(last_name || '').humanize.titleize}"
|
||||
end
|
||||
end
|
||||
|
@ -1,4 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# ProfileCustomFields are customer fields, configured by an admin, added to the user's profile
|
||||
class ProfileCustomField < ApplicationRecord
|
||||
has_many :user_profile_custom_fields
|
||||
has_many :user_profile_custom_fields, dependent: :destroy
|
||||
has_many :invoicing_profiles, through: :user_profile_custom_fields
|
||||
end
|
||||
|
@ -1,3 +1,6 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# UserProfileCustomField store values for custom fields per user's profile
|
||||
class UserProfileCustomField < ApplicationRecord
|
||||
belongs_to :invoicing_profile
|
||||
belongs_to :profile_custom_field
|
||||
|
@ -57,7 +57,7 @@ class Accounting::AccountingCodeService
|
||||
raise ArgumentError('invalid section') unless %i[code analytical_section].include?(section)
|
||||
|
||||
if type == :code
|
||||
item_code = Setting.get('advanced_accounting') ? invoice_item.object.plan.advanced_accounting.send(section) : nil
|
||||
item_code = Setting.get('advanced_accounting') ? invoice_item.object.plan.advanced_accounting&.send(section) : nil
|
||||
return Setting.get('accounting_subscription_code') if item_code.nil? && section == :code
|
||||
|
||||
item_code
|
||||
@ -71,7 +71,7 @@ class Accounting::AccountingCodeService
|
||||
raise ArgumentError('invalid section') unless %i[code analytical_section].include?(section)
|
||||
|
||||
if type == :code
|
||||
item_code = Setting.get('advanced_accounting') ? invoice_item.object.orderable.advanced_accounting.send(section) : nil
|
||||
item_code = Setting.get('advanced_accounting') ? invoice_item.object.orderable.advanced_accounting&.send(section) : nil
|
||||
return Setting.get('accounting_Product_code') if item_code.nil? && section == :code
|
||||
|
||||
item_code
|
||||
|
@ -7,8 +7,7 @@ module Accounting; end
|
||||
class Accounting::AccountingExportService
|
||||
include ActionView::Helpers::NumberHelper
|
||||
|
||||
attr_reader :encoding, :format, :separator, :journal_code, :date_format, :columns, :decimal_separator, :label_max_length,
|
||||
:export_zeros
|
||||
attr_reader :encoding, :format, :separator, :date_format, :columns, :decimal_separator, :label_max_length, :export_zeros
|
||||
|
||||
def initialize(columns, encoding: 'UTF-8', format: 'CSV', separator: ';')
|
||||
@encoding = encoding
|
||||
@ -18,7 +17,6 @@ class Accounting::AccountingExportService
|
||||
@date_format = '%d/%m/%Y'
|
||||
@label_max_length = 50
|
||||
@export_zeros = false
|
||||
@journal_code = Setting.get('accounting_journal_code') || ''
|
||||
@columns = columns
|
||||
end
|
||||
|
||||
@ -32,11 +30,12 @@ class Accounting::AccountingExportService
|
||||
def export(start_date, end_date, file)
|
||||
# build CSV content
|
||||
content = header_row
|
||||
invoices = Invoice.where('created_at >= ? AND created_at <= ?', start_date, end_date).order('created_at ASC')
|
||||
invoices = invoices.where('total > 0') unless export_zeros
|
||||
invoices.each do |i|
|
||||
Rails.logger.debug { "processing invoice #{i.id}..." } unless Rails.env.test?
|
||||
content << generate_rows(i)
|
||||
lines = AccountingLine.where('date >= ? AND date <= ?', start_date, end_date)
|
||||
.order('date ASC')
|
||||
lines = lines.joins(:invoice).where('invoices.total > 0') unless export_zeros
|
||||
lines.each do |l|
|
||||
Rails.logger.debug { "processing invoice #{l.invoice_id}..." } unless Rails.env.test?
|
||||
content << "#{row(l)}\n"
|
||||
end
|
||||
|
||||
# write content to file
|
||||
@ -53,138 +52,46 @@ class Accounting::AccountingExportService
|
||||
"#{row}\n"
|
||||
end
|
||||
|
||||
def generate_rows(invoice)
|
||||
rows = client_rows(invoice) + items_rows(invoice)
|
||||
|
||||
vat = vat_row(invoice)
|
||||
rows += "#{vat}\n" unless vat.nil?
|
||||
|
||||
rows
|
||||
end
|
||||
|
||||
# Generate the "subscription" and "reservation" rows associated with the provided invoice
|
||||
def items_rows(invoice)
|
||||
rows = ''
|
||||
%w[Subscription Reservation WalletTransaction StatisticProfilePrepaidPack OrderItem Error].each do |object_type|
|
||||
items = invoice.invoice_items.filter { |ii| ii.object_type == object_type }
|
||||
items.each do |item|
|
||||
rows << "#{row(
|
||||
invoice,
|
||||
Accounting::AccountingCodeService.sales_account(item),
|
||||
Accounting::AccountingCodeService.sales_account(item, type: :label),
|
||||
item.net_amount / 100.00,
|
||||
line_label: label(invoice)
|
||||
)}\n"
|
||||
end
|
||||
end
|
||||
rows
|
||||
end
|
||||
|
||||
# Generate the "client" rows, which contains the debit to the client account, all taxes included
|
||||
def client_rows(invoice)
|
||||
rows = ''
|
||||
invoice.payment_means.each do |details|
|
||||
rows << row(
|
||||
invoice,
|
||||
Accounting::AccountingCodeService.client_account(details[:means]),
|
||||
Accounting::AccountingCodeService.client_account(details[:means], type: :label),
|
||||
details[:amount] / 100.00,
|
||||
line_label: label(invoice),
|
||||
debit_method: :debit_client,
|
||||
credit_method: :credit_client
|
||||
)
|
||||
rows << "\n"
|
||||
end
|
||||
rows
|
||||
end
|
||||
|
||||
# Generate the "VAT" row, which contains the credit to the VAT account, with VAT amount only
|
||||
def vat_row(invoice)
|
||||
total = invoice.invoice_items.map(&:net_amount).sum
|
||||
# we do not render the VAT row if it was disabled for this invoice
|
||||
return nil if total == invoice.total
|
||||
|
||||
row(
|
||||
invoice,
|
||||
Accounting::AccountingCodeService.vat_account,
|
||||
Accounting::AccountingCodeService.vat_account(type: :label),
|
||||
invoice.invoice_items.map(&:vat).map(&:to_i).reduce(:+) / 100.00,
|
||||
line_label: label(invoice)
|
||||
)
|
||||
end
|
||||
|
||||
# Generate a row of the export, filling the configured columns with the provided values
|
||||
def row(invoice, account_code, account_label, amount, line_label: '', debit_method: :debit, credit_method: :credit)
|
||||
def row(line)
|
||||
row = ''
|
||||
columns.each do |column|
|
||||
case column
|
||||
when 'journal_code'
|
||||
row << journal_code.to_s
|
||||
row << line.journal_code.to_s
|
||||
when 'date'
|
||||
row << invoice.created_at&.strftime(date_format)
|
||||
row << line.date&.strftime(date_format)
|
||||
when 'account_code'
|
||||
row << account_code
|
||||
row << line.account_code
|
||||
when 'account_label'
|
||||
row << account_label
|
||||
row << line.account_label
|
||||
when 'piece'
|
||||
row << invoice.reference
|
||||
row << line.invoice.reference
|
||||
when 'line_label'
|
||||
row << line_label
|
||||
row << label(line)
|
||||
when 'debit_origin', 'debit_euro'
|
||||
row << method(debit_method).call(invoice, amount)
|
||||
row << format_number(line.debit / 100.00)
|
||||
when 'credit_origin', 'credit_euro'
|
||||
row << method(credit_method).call(invoice, amount)
|
||||
row << format_number(line.credit / 100.00)
|
||||
when 'lettering'
|
||||
row << ''
|
||||
else
|
||||
Rails.logger.debug { "Unsupported column: #{column}" }
|
||||
Rails.logger.warn { "Unsupported column: #{column}" }
|
||||
end
|
||||
row << separator
|
||||
end
|
||||
row
|
||||
end
|
||||
|
||||
# Fill the value of the "debit" column: if the invoice is a refund, returns the given amount, returns 0 otherwise
|
||||
def debit(invoice, amount)
|
||||
avoir = invoice.is_a? Avoir
|
||||
avoir ? format_number(amount) : '0'
|
||||
end
|
||||
|
||||
# Fill the value of the "credit" column: if the invoice is a refund, returns 0, otherwise, returns the given amount
|
||||
def credit(invoice, amount)
|
||||
avoir = invoice.is_a? Avoir
|
||||
avoir ? '0' : format_number(amount)
|
||||
end
|
||||
|
||||
# Fill the value of the "debit" column for the client row: if the invoice is a refund, returns 0, otherwise, returns the given amount
|
||||
def debit_client(invoice, amount)
|
||||
credit(invoice, amount)
|
||||
end
|
||||
|
||||
# Fill the value of the "credit" column, for the client row: if the invoice is a refund, returns the given amount, returns 0 otherwise
|
||||
def credit_client(invoice, amount)
|
||||
debit(invoice, amount)
|
||||
end
|
||||
|
||||
# Format the given number as a string, using the configured separator
|
||||
def format_number(num)
|
||||
number_to_currency(num, unit: '', separator: decimal_separator, delimiter: '', precision: 2)
|
||||
end
|
||||
|
||||
# Create a text from the given invoice, matching the accounting software rules for the labels
|
||||
def label(invoice)
|
||||
name = "#{invoice.invoicing_profile.last_name} #{invoice.invoicing_profile.first_name}".tr separator, ''
|
||||
reference = invoice.reference
|
||||
|
||||
items = invoice.subscription_invoice? ? [I18n.t('accounting_export.subscription')] : []
|
||||
if invoice.main_item.object_type == 'Reservation'
|
||||
items.push I18n.t("accounting_export.#{invoice.main_item.object.reservable_type}_reservation")
|
||||
end
|
||||
items.push I18n.t('accounting_export.wallet') if invoice.main_item.object_type == 'WalletTransaction'
|
||||
items.push I18n.t('accounting_export.shop_order') if invoice.main_item.object_type == 'OrderItem'
|
||||
|
||||
summary = items.join(' + ')
|
||||
res = "#{reference}, #{summary}"
|
||||
"#{name.truncate(label_max_length - res.length)}, #{res}"
|
||||
def label(line)
|
||||
name = "#{line.invoicing_profile.last_name} #{line.invoicing_profile.first_name}".tr separator, ''
|
||||
summary = line.summary
|
||||
"#{name.truncate(label_max_length - summary.length)}, #{summary}"
|
||||
end
|
||||
end
|
||||
|
140
app/services/accounting/accounting_service.rb
Normal file
140
app/services/accounting/accounting_service.rb
Normal file
@ -0,0 +1,140 @@
|
||||
# frozen_string_literal: false
|
||||
|
||||
# module definition
|
||||
module Accounting; end
|
||||
|
||||
# Provides the routine to build the accounting data and save them in DB
|
||||
class Accounting::AccountingService
|
||||
attr_reader :currency, :journal_code
|
||||
|
||||
def initialize
|
||||
@currency = ENV.fetch('INTL_CURRENCY') { '' }
|
||||
@journal_code = Setting.get('accounting_journal_code') || ''
|
||||
end
|
||||
|
||||
def build(start_date, end_date)
|
||||
# build accounting lines
|
||||
lines = []
|
||||
invoices = Invoice.where('created_at >= ? AND created_at <= ?', start_date, end_date).order('created_at ASC')
|
||||
invoices.each do |i|
|
||||
Rails.logger.debug { "processing invoice #{i.id}..." } unless Rails.env.test?
|
||||
lines << generate_lines(i)
|
||||
end
|
||||
AccountingLine.create!(lines)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def generate_lines(invoice)
|
||||
lines = client_lines(invoice) + items_lines(invoice)
|
||||
|
||||
vat = vat_line(invoice)
|
||||
lines << vat unless vat.nil?
|
||||
|
||||
lines
|
||||
end
|
||||
|
||||
# Generate the lines associated with the provided invoice, for the sales accounts
|
||||
def items_lines(invoice)
|
||||
lines = []
|
||||
%w[Subscription Reservation WalletTransaction StatisticProfilePrepaidPack OrderItem Error].each do |object_type|
|
||||
items = invoice.invoice_items.filter { |ii| ii.object_type == object_type }
|
||||
items.each do |item|
|
||||
lines << line(
|
||||
invoice,
|
||||
'item',
|
||||
Accounting::AccountingCodeService.sales_account(item),
|
||||
Accounting::AccountingCodeService.sales_account(item, type: :label),
|
||||
item.net_amount,
|
||||
analytical_code: Accounting::AccountingCodeService.sales_account(item, section: :analytical_section)
|
||||
)
|
||||
end
|
||||
end
|
||||
lines
|
||||
end
|
||||
|
||||
# Generate the "client" lines, which contains the debit to the client account, all taxes included
|
||||
def client_lines(invoice)
|
||||
lines = []
|
||||
invoice.payment_means.each do |details|
|
||||
lines << line(
|
||||
invoice,
|
||||
'client',
|
||||
Accounting::AccountingCodeService.client_account(details[:means]),
|
||||
Accounting::AccountingCodeService.client_account(details[:means], type: :label),
|
||||
details[:amount],
|
||||
debit_method: :debit_client,
|
||||
credit_method: :credit_client
|
||||
)
|
||||
end
|
||||
lines
|
||||
end
|
||||
|
||||
# Generate the "VAT" line, which contains the credit to the VAT account, with total VAT amount only
|
||||
def vat_line(invoice)
|
||||
vat_rate_groups = VatHistoryService.new.invoice_vat(invoice)
|
||||
total_vat = vat_rate_groups.values.pluck(:total_vat).sum
|
||||
# we do not render the VAT row if it was disabled for this invoice
|
||||
return nil if total_vat.zero?
|
||||
|
||||
line(
|
||||
invoice,
|
||||
'vat',
|
||||
Accounting::AccountingCodeService.vat_account,
|
||||
Accounting::AccountingCodeService.vat_account(type: :label),
|
||||
total_vat
|
||||
)
|
||||
end
|
||||
|
||||
# Generate a row of the export, filling the configured columns with the provided values
|
||||
def line(invoice, line_type, account_code, account_label, amount, analytical_code: '', debit_method: :debit, credit_method: :credit)
|
||||
{
|
||||
line_type: line_type,
|
||||
journal_code: journal_code,
|
||||
date: invoice.created_at,
|
||||
account_code: account_code,
|
||||
account_label: account_label,
|
||||
analytical_code: analytical_code,
|
||||
invoice_id: invoice.id,
|
||||
invoicing_profile_id: invoice.invoicing_profile_id,
|
||||
debit: method(debit_method).call(invoice, amount),
|
||||
credit: method(credit_method).call(invoice, amount),
|
||||
currency: currency,
|
||||
summary: summary(invoice)
|
||||
}
|
||||
end
|
||||
|
||||
# Fill the value of the "debit" column: if the invoice is a refund, returns the given amount, returns 0 otherwise
|
||||
def debit(invoice, amount)
|
||||
invoice.is_a?(Avoir) ? amount : 0
|
||||
end
|
||||
|
||||
# Fill the value of the "credit" column: if the invoice is a refund, returns 0, otherwise, returns the given amount
|
||||
def credit(invoice, amount)
|
||||
invoice.is_a?(Avoir) ? 0 : amount
|
||||
end
|
||||
|
||||
# Fill the value of the "debit" column for the client row: if the invoice is a refund, returns 0, otherwise, returns the given amount
|
||||
def debit_client(invoice, amount)
|
||||
credit(invoice, amount)
|
||||
end
|
||||
|
||||
# Fill the value of the "credit" column, for the client row: if the invoice is a refund, returns the given amount, returns 0 otherwise
|
||||
def credit_client(invoice, amount)
|
||||
debit(invoice, amount)
|
||||
end
|
||||
|
||||
# Create a text from the given invoice, matching the accounting software rules for the labels
|
||||
def summary(invoice)
|
||||
reference = invoice.reference
|
||||
|
||||
items = invoice.subscription_invoice? ? [I18n.t('accounting_summary.subscription_abbreviation')] : []
|
||||
if invoice.main_item.object_type == 'Reservation'
|
||||
items.push I18n.t("accounting_summary.#{invoice.main_item.object.reservable_type}_reservation_abbreviation")
|
||||
end
|
||||
items.push I18n.t('accounting_summary.wallet_abbreviation') if invoice.main_item.object_type == 'WalletTransaction'
|
||||
items.push I18n.t('accounting_summary.shop_order_abbreviation') if invoice.main_item.object_type == 'OrderItem'
|
||||
|
||||
"#{reference}, #{items.join(' + ')}"
|
||||
end
|
||||
end
|
@ -1,6 +1,6 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Asynchronously export the accounting data (Invoices & Avoirs) to an external accounting software
|
||||
# Asynchronously export the accounting data (AccountingLines) to an external accounting software
|
||||
class AccountingExportWorker
|
||||
include Sidekiq::Worker
|
||||
|
||||
|
11
app/workers/accounting_worker.rb
Normal file
11
app/workers/accounting_worker.rb
Normal file
@ -0,0 +1,11 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Periodically build the accounting data (AccountingLine) from the Invoices & Avoirs
|
||||
class AccountingWorker
|
||||
include Sidekiq::Worker
|
||||
|
||||
def perform
|
||||
service = Accounting::AccountingService.new
|
||||
service.build(DateTime.current.beginning_of_day, DateTime.current.end_of_day)
|
||||
end
|
||||
end
|
@ -158,13 +158,14 @@ en:
|
||||
credit_euro: "Euro credit"
|
||||
lettering: "Lettering"
|
||||
VAT: 'VAT'
|
||||
subscription: "subscr."
|
||||
Machine_reservation: "machine reserv."
|
||||
Training_reservation: "training reserv."
|
||||
Event_reservation: "event reserv."
|
||||
Space_reservation: "space reserv."
|
||||
wallet: "wallet"
|
||||
shop_order: "shop order"
|
||||
accounting_summary:
|
||||
subscription_abbreviation: "subscr."
|
||||
Machine_reservation_abbreviation: "machine reserv."
|
||||
Training_reservation_abbreviation: "training reserv."
|
||||
Event_reservation_abbreviation: "event reserv."
|
||||
Space_reservation_abbreviation: "space reserv."
|
||||
wallet_abbreviation: "wallet"
|
||||
shop_order_abbreviation: "shop order"
|
||||
vat_export:
|
||||
start_date: "Start date"
|
||||
end_date: "End date"
|
||||
|
@ -1,27 +1,27 @@
|
||||
subscription_expire_in_7_days:
|
||||
cron: "0 0 * * *"
|
||||
cron: "0 0 * * *" # every day, at midnight
|
||||
class: SubscriptionExpireWorker
|
||||
queue: default
|
||||
args: [7]
|
||||
|
||||
subscription_is_expired:
|
||||
cron: "0 23 * * *"
|
||||
cron: "0 23 * * *" # every day, at 11pm
|
||||
class: SubscriptionExpireWorker
|
||||
queue: default
|
||||
args: [0]
|
||||
|
||||
generate_statistic:
|
||||
cron: "0 1 * * *"
|
||||
cron: "0 1 * * *" # every day, at 1am
|
||||
class: StatisticWorker
|
||||
queue: default
|
||||
|
||||
i_calendar_import:
|
||||
cron: "0 * * * *"
|
||||
cron: "0 * * * *" # every day, every hour
|
||||
class: ICalendarImportWorker
|
||||
queue: default
|
||||
|
||||
reservation_reminder:
|
||||
cron: "1 * * * *"
|
||||
cron: "1 * * * *" # every day, every hour + 1 minute
|
||||
class: ReservationReminderWorker
|
||||
queue: default
|
||||
|
||||
@ -35,11 +35,10 @@ free_disk_space:
|
||||
class: FreeDiskSpaceWorker
|
||||
queue: system
|
||||
|
||||
# schedule a version check, every week at the current day+time
|
||||
# this will prevent that all the instances query the hub simultaneously
|
||||
<% h = DateTime.current - 1.minute %>
|
||||
version_check:
|
||||
cron: <%="#{h.strftime('%M %H')} * * #{h.cwday}" %>
|
||||
cron: <%="#{h.strftime('%M %H')} * * #{h.cwday}" %> # every week, at current day+time
|
||||
class: VersionCheckWorker
|
||||
queue: system
|
||||
|
||||
@ -48,4 +47,9 @@ payment_schedule_item:
|
||||
class: PaymentScheduleItemWorker
|
||||
queue: default
|
||||
|
||||
accounting_data:
|
||||
cron: "0 0 * * *" # every day, at midnight
|
||||
class: AccountingWorker
|
||||
queue: default
|
||||
|
||||
<%= PluginRegistry.insert_code('yml.schedule') %>
|
||||
|
24
db/migrate/20221118092948_create_accounting_lines.rb
Normal file
24
db/migrate/20221118092948_create_accounting_lines.rb
Normal file
@ -0,0 +1,24 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# From this migration we save the accounting lines in database rather than building them on-the-fly.
|
||||
# This will improve performance for API based requests
|
||||
class CreateAccountingLines < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
create_table :accounting_lines do |t|
|
||||
t.string :line_type
|
||||
t.string :journal_code
|
||||
t.datetime :date
|
||||
t.string :account_code
|
||||
t.string :account_label
|
||||
t.string :analytical_code
|
||||
t.references :invoice, foreign_key: true, index: true
|
||||
t.references :invoicing_profile, foreign_key: true, index: true
|
||||
t.integer :debit
|
||||
t.integer :credit
|
||||
t.string :currency
|
||||
t.string :summary
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
39
db/schema.rb
39
db/schema.rb
@ -19,8 +19,8 @@ ActiveRecord::Schema.define(version: 2022_11_22_123605) do
|
||||
enable_extension "unaccent"
|
||||
|
||||
create_table "abuses", id: :serial, force: :cascade do |t|
|
||||
t.integer "signaled_id"
|
||||
t.string "signaled_type"
|
||||
t.integer "signaled_id"
|
||||
t.string "first_name"
|
||||
t.string "last_name"
|
||||
t.string "email"
|
||||
@ -30,6 +30,25 @@ ActiveRecord::Schema.define(version: 2022_11_22_123605) do
|
||||
t.index ["signaled_type", "signaled_id"], name: "index_abuses_on_signaled_type_and_signaled_id"
|
||||
end
|
||||
|
||||
create_table "accounting_lines", force: :cascade do |t|
|
||||
t.string "line_type"
|
||||
t.string "journal_code"
|
||||
t.datetime "date"
|
||||
t.string "account_code"
|
||||
t.string "account_label"
|
||||
t.string "analytical_code"
|
||||
t.bigint "invoice_id"
|
||||
t.bigint "invoicing_profile_id"
|
||||
t.integer "debit"
|
||||
t.integer "credit"
|
||||
t.string "currency"
|
||||
t.string "summary"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["invoice_id"], name: "index_accounting_lines_on_invoice_id"
|
||||
t.index ["invoicing_profile_id"], name: "index_accounting_lines_on_invoicing_profile_id"
|
||||
end
|
||||
|
||||
create_table "accounting_periods", id: :serial, force: :cascade do |t|
|
||||
t.date "start_at"
|
||||
t.date "end_at"
|
||||
@ -49,8 +68,8 @@ ActiveRecord::Schema.define(version: 2022_11_22_123605) do
|
||||
t.string "locality"
|
||||
t.string "country"
|
||||
t.string "postal_code"
|
||||
t.integer "placeable_id"
|
||||
t.string "placeable_type"
|
||||
t.integer "placeable_id"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
end
|
||||
@ -74,8 +93,8 @@ ActiveRecord::Schema.define(version: 2022_11_22_123605) do
|
||||
end
|
||||
|
||||
create_table "assets", id: :serial, force: :cascade do |t|
|
||||
t.integer "viewable_id"
|
||||
t.string "viewable_type"
|
||||
t.integer "viewable_id"
|
||||
t.string "attachment"
|
||||
t.string "type"
|
||||
t.datetime "created_at"
|
||||
@ -157,8 +176,8 @@ ActiveRecord::Schema.define(version: 2022_11_22_123605) do
|
||||
end
|
||||
|
||||
create_table "credits", id: :serial, force: :cascade do |t|
|
||||
t.integer "creditable_id"
|
||||
t.string "creditable_type"
|
||||
t.integer "creditable_id"
|
||||
t.integer "plan_id"
|
||||
t.integer "hours"
|
||||
t.datetime "created_at"
|
||||
@ -387,15 +406,15 @@ ActiveRecord::Schema.define(version: 2022_11_22_123605) do
|
||||
|
||||
create_table "notifications", id: :serial, force: :cascade do |t|
|
||||
t.integer "receiver_id"
|
||||
t.integer "attached_object_id"
|
||||
t.string "attached_object_type"
|
||||
t.integer "attached_object_id"
|
||||
t.integer "notification_type_id"
|
||||
t.boolean "is_read", default: false
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.string "receiver_type"
|
||||
t.boolean "is_send", default: false
|
||||
t.jsonb "meta_data", default: {}
|
||||
t.jsonb "meta_data", default: "{}"
|
||||
t.index ["notification_type_id"], name: "index_notifications_on_notification_type_id"
|
||||
t.index ["receiver_id"], name: "index_notifications_on_receiver_id"
|
||||
end
|
||||
@ -635,8 +654,8 @@ ActiveRecord::Schema.define(version: 2022_11_22_123605) do
|
||||
create_table "prices", id: :serial, force: :cascade do |t|
|
||||
t.integer "group_id"
|
||||
t.integer "plan_id"
|
||||
t.integer "priceable_id"
|
||||
t.string "priceable_type"
|
||||
t.integer "priceable_id"
|
||||
t.integer "amount"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
@ -836,8 +855,8 @@ ActiveRecord::Schema.define(version: 2022_11_22_123605) do
|
||||
t.text "message"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.integer "reservable_id"
|
||||
t.string "reservable_type"
|
||||
t.integer "reservable_id"
|
||||
t.integer "nb_reserve_places"
|
||||
t.integer "statistic_profile_id"
|
||||
t.index ["reservable_type", "reservable_id"], name: "index_reservations_on_reservable_type_and_reservable_id"
|
||||
@ -846,8 +865,8 @@ ActiveRecord::Schema.define(version: 2022_11_22_123605) do
|
||||
|
||||
create_table "roles", id: :serial, force: :cascade do |t|
|
||||
t.string "name"
|
||||
t.integer "resource_id"
|
||||
t.string "resource_type"
|
||||
t.integer "resource_id"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.index ["name", "resource_type", "resource_id"], name: "index_roles_on_name_and_resource_type_and_resource_id"
|
||||
@ -1178,6 +1197,8 @@ ActiveRecord::Schema.define(version: 2022_11_22_123605) do
|
||||
t.index ["invoicing_profile_id"], name: "index_wallets_on_invoicing_profile_id"
|
||||
end
|
||||
|
||||
add_foreign_key "accounting_lines", "invoices"
|
||||
add_foreign_key "accounting_lines", "invoicing_profiles"
|
||||
add_foreign_key "accounting_periods", "users", column: "closed_by"
|
||||
add_foreign_key "auth_provider_mappings", "auth_providers"
|
||||
add_foreign_key "availability_tags", "availabilities"
|
||||
|
544
test/fixtures/accounting_lines.yml
vendored
Normal file
544
test/fixtures/accounting_lines.yml
vendored
Normal file
@ -0,0 +1,544 @@
|
||||
accounting_line_1:
|
||||
id: 1
|
||||
line_type: client
|
||||
journal_code: '530'
|
||||
date: '2012-03-12 11:03:31.651441'
|
||||
account_code: '5801'
|
||||
account_label: Client card
|
||||
analytical_code: ''
|
||||
invoice_id: 1
|
||||
invoicing_profile_id: 3
|
||||
debit: 10000
|
||||
credit: 0
|
||||
currency: EUR
|
||||
summary: 1604001/VL, subscr.
|
||||
created_at: '2022-11-18 15:04:08.437029'
|
||||
updated_at: '2022-11-18 15:04:08.437029'
|
||||
accounting_line_2:
|
||||
id: 2
|
||||
line_type: item
|
||||
journal_code: '530'
|
||||
date: '2012-03-12 11:03:31.651441'
|
||||
account_code: '7061'
|
||||
account_label: Subscription
|
||||
analytical_code:
|
||||
invoice_id: 1
|
||||
invoicing_profile_id: 3
|
||||
debit: 0
|
||||
credit: 10000
|
||||
currency: EUR
|
||||
summary: 1604001/VL, subscr.
|
||||
created_at: '2022-11-18 15:04:08.455753'
|
||||
updated_at: '2022-11-18 15:04:08.455753'
|
||||
accounting_line_3:
|
||||
id: 3
|
||||
line_type: client
|
||||
journal_code: '530'
|
||||
date: '2012-03-12 13:40:22.342717'
|
||||
account_code: '5803'
|
||||
account_label: Client other
|
||||
analytical_code: ''
|
||||
invoice_id: 2
|
||||
invoicing_profile_id: 4
|
||||
debit: 2000
|
||||
credit: 0
|
||||
currency: EUR
|
||||
summary: 1604002, subscr.
|
||||
created_at: '2022-11-18 15:04:08.463802'
|
||||
updated_at: '2022-11-18 15:04:08.463802'
|
||||
accounting_line_4:
|
||||
id: 4
|
||||
line_type: item
|
||||
journal_code: '530'
|
||||
date: '2012-03-12 13:40:22.342717'
|
||||
account_code: '7061'
|
||||
account_label: Subscription
|
||||
analytical_code:
|
||||
invoice_id: 2
|
||||
invoicing_profile_id: 4
|
||||
debit: 0
|
||||
credit: 2000
|
||||
currency: EUR
|
||||
summary: 1604002, subscr.
|
||||
created_at: '2022-11-18 15:04:08.471904'
|
||||
updated_at: '2022-11-18 15:04:08.471904'
|
||||
accounting_line_5:
|
||||
id: 5
|
||||
line_type: client
|
||||
journal_code: '530'
|
||||
date: '2015-06-10 11:20:01.341130'
|
||||
account_code: '5803'
|
||||
account_label: Client other
|
||||
analytical_code: ''
|
||||
invoice_id: 3
|
||||
invoicing_profile_id: 7
|
||||
debit: 3000
|
||||
credit: 0
|
||||
currency: EUR
|
||||
summary: 1203001, subscr.
|
||||
created_at: '2022-11-18 15:04:08.480362'
|
||||
updated_at: '2022-11-18 15:04:08.480362'
|
||||
accounting_line_6:
|
||||
id: 6
|
||||
line_type: item
|
||||
journal_code: '530'
|
||||
date: '2015-06-10 11:20:01.341130'
|
||||
account_code: '7061'
|
||||
account_label: Subscription
|
||||
analytical_code:
|
||||
invoice_id: 3
|
||||
invoicing_profile_id: 7
|
||||
debit: 0
|
||||
credit: 3000
|
||||
currency: EUR
|
||||
summary: 1203001, subscr.
|
||||
created_at: '2022-11-18 15:04:08.488755'
|
||||
updated_at: '2022-11-18 15:04:08.488755'
|
||||
accounting_line_7:
|
||||
id: 7
|
||||
line_type: client
|
||||
journal_code: '530'
|
||||
date: '2016-04-05 08:35:52.931187'
|
||||
account_code: '5803'
|
||||
account_label: Client other
|
||||
analytical_code: ''
|
||||
invoice_id: 4
|
||||
invoicing_profile_id: 7
|
||||
debit: 0
|
||||
credit: 0
|
||||
currency: EUR
|
||||
summary: 1203002, training reserv.
|
||||
created_at: '2022-11-18 15:04:08.497148'
|
||||
updated_at: '2022-11-18 15:04:08.497148'
|
||||
accounting_line_8:
|
||||
id: 8
|
||||
line_type: item
|
||||
journal_code: '530'
|
||||
date: '2016-04-05 08:35:52.931187'
|
||||
account_code: '7062'
|
||||
account_label: Training reservation
|
||||
analytical_code:
|
||||
invoice_id: 4
|
||||
invoicing_profile_id: 7
|
||||
debit: 0
|
||||
credit: 0
|
||||
currency: EUR
|
||||
summary: 1203002, training reserv.
|
||||
created_at: '2022-11-18 15:04:08.505540'
|
||||
updated_at: '2022-11-18 15:04:08.505540'
|
||||
accounting_line_9:
|
||||
id: 9
|
||||
line_type: client
|
||||
journal_code: '530'
|
||||
date: '2016-04-05 08:36:46.853368'
|
||||
account_code: '5803'
|
||||
account_label: Client other
|
||||
analytical_code: ''
|
||||
invoice_id: 5
|
||||
invoicing_profile_id: 3
|
||||
debit: 1500
|
||||
credit: 0
|
||||
currency: EUR
|
||||
summary: 1506031, machine reserv.
|
||||
created_at: '2022-11-18 15:04:08.513708'
|
||||
updated_at: '2022-11-18 15:04:08.513708'
|
||||
accounting_line_10:
|
||||
id: 10
|
||||
line_type: item
|
||||
journal_code: '530'
|
||||
date: '2016-04-05 08:36:46.853368'
|
||||
account_code: '7065'
|
||||
account_label: Machine reservation
|
||||
analytical_code:
|
||||
invoice_id: 5
|
||||
invoicing_profile_id: 3
|
||||
debit: 0
|
||||
credit: 1500
|
||||
currency: EUR
|
||||
summary: 1506031, machine reserv.
|
||||
created_at: '2022-11-18 15:04:08.522222'
|
||||
updated_at: '2022-11-18 15:04:08.522222'
|
||||
accounting_line_11:
|
||||
id: 11
|
||||
line_type: client
|
||||
journal_code: '530'
|
||||
date: '2021-01-04 14:51:21.616153'
|
||||
account_code: '5803'
|
||||
account_label: Client other
|
||||
analytical_code: ''
|
||||
invoice_id: 6
|
||||
invoicing_profile_id: 8
|
||||
debit: 3000
|
||||
credit: 0
|
||||
currency: EUR
|
||||
summary: 2101041, subscr.
|
||||
created_at: '2022-11-18 15:04:08.530494'
|
||||
updated_at: '2022-11-18 15:04:08.530494'
|
||||
accounting_line_12:
|
||||
id: 12
|
||||
line_type: item
|
||||
journal_code: '530'
|
||||
date: '2021-01-04 14:51:21.616153'
|
||||
account_code: '7061'
|
||||
account_label: Subscription
|
||||
analytical_code:
|
||||
invoice_id: 6
|
||||
invoicing_profile_id: 8
|
||||
debit: 0
|
||||
credit: 3000
|
||||
currency: EUR
|
||||
summary: 2101041, subscr.
|
||||
created_at: '2022-11-18 15:04:08.538721'
|
||||
updated_at: '2022-11-18 15:04:08.538721'
|
||||
accounting_line_13:
|
||||
id: 13
|
||||
line_type: client
|
||||
journal_code: '530'
|
||||
date: '2022-09-20 15:14:22.873707'
|
||||
account_code: '5803'
|
||||
account_label: Client other
|
||||
analytical_code: ''
|
||||
invoice_id: 5811
|
||||
invoicing_profile_id: 3
|
||||
debit: 4500
|
||||
credit: 0
|
||||
currency: EUR
|
||||
summary: 2209002, shop order
|
||||
created_at: '2022-11-18 15:04:08.547966'
|
||||
updated_at: '2022-11-18 15:04:08.547966'
|
||||
accounting_line_14:
|
||||
id: 14
|
||||
line_type: item
|
||||
journal_code: '530'
|
||||
date: '2022-09-20 15:14:22.873707'
|
||||
account_code: '7067'
|
||||
account_label: Shop order
|
||||
analytical_code:
|
||||
invoice_id: 5811
|
||||
invoicing_profile_id: 3
|
||||
debit: 0
|
||||
credit: 4000
|
||||
currency: EUR
|
||||
summary: 2209002, shop order
|
||||
created_at: '2022-11-18 15:04:08.556504'
|
||||
updated_at: '2022-11-18 15:04:08.556504'
|
||||
accounting_line_15:
|
||||
id: 15
|
||||
line_type: item
|
||||
journal_code: '530'
|
||||
date: '2022-09-20 15:14:22.873707'
|
||||
account_code: '7067'
|
||||
account_label: Shop order
|
||||
analytical_code:
|
||||
invoice_id: 5811
|
||||
invoicing_profile_id: 3
|
||||
debit: 0
|
||||
credit: 500
|
||||
currency: EUR
|
||||
summary: 2209002, shop order
|
||||
created_at: '2022-11-18 15:04:08.563733'
|
||||
updated_at: '2022-11-18 15:04:08.563733'
|
||||
accounting_line_16:
|
||||
id: 16
|
||||
line_type: client
|
||||
journal_code: '530'
|
||||
date: '2022-09-20 15:14:48.345927'
|
||||
account_code: '5803'
|
||||
account_label: Client other
|
||||
analytical_code: ''
|
||||
invoice_id: 5812
|
||||
invoicing_profile_id: 7
|
||||
debit: 6000
|
||||
credit: 0
|
||||
currency: EUR
|
||||
summary: 2209004, shop order
|
||||
created_at: '2022-11-18 15:04:08.571992'
|
||||
updated_at: '2022-11-18 15:04:08.571992'
|
||||
accounting_line_17:
|
||||
id: 17
|
||||
line_type: item
|
||||
journal_code: '530'
|
||||
date: '2022-09-20 15:14:48.345927'
|
||||
account_code: '7067'
|
||||
account_label: Shop order
|
||||
analytical_code:
|
||||
invoice_id: 5812
|
||||
invoicing_profile_id: 7
|
||||
debit: 0
|
||||
credit: 6000
|
||||
currency: EUR
|
||||
summary: 2209004, shop order
|
||||
created_at: '2022-11-18 15:04:08.580452'
|
||||
updated_at: '2022-11-18 15:04:08.580452'
|
||||
accounting_line_18:
|
||||
id: 18
|
||||
line_type: client
|
||||
journal_code: '530'
|
||||
date: '2022-10-04 12:36:03.060832'
|
||||
account_code: '5801'
|
||||
account_label: Client card
|
||||
analytical_code: ''
|
||||
invoice_id: 5816
|
||||
invoicing_profile_id: 4
|
||||
debit: 319
|
||||
credit: 0
|
||||
currency: EUR
|
||||
summary: 2210002/VL, shop order
|
||||
created_at: '2022-11-18 15:04:08.589664'
|
||||
updated_at: '2022-11-18 15:04:08.589664'
|
||||
accounting_line_19:
|
||||
id: 19
|
||||
line_type: item
|
||||
journal_code: '530'
|
||||
date: '2022-10-04 12:36:03.060832'
|
||||
account_code: '7067'
|
||||
account_label: Shop order
|
||||
analytical_code:
|
||||
invoice_id: 5816
|
||||
invoicing_profile_id: 4
|
||||
debit: 0
|
||||
credit: 119
|
||||
currency: EUR
|
||||
summary: 2210002/VL, shop order
|
||||
created_at: '2022-11-18 15:04:08.598371'
|
||||
updated_at: '2022-11-18 15:04:08.598371'
|
||||
accounting_line_20:
|
||||
id: 20
|
||||
line_type: item
|
||||
journal_code: '530'
|
||||
date: '2022-10-04 12:36:03.060832'
|
||||
account_code: '7067'
|
||||
account_label: Shop order
|
||||
analytical_code:
|
||||
invoice_id: 5816
|
||||
invoicing_profile_id: 4
|
||||
debit: 0
|
||||
credit: 200
|
||||
currency: EUR
|
||||
summary: 2210002/VL, shop order
|
||||
created_at: '2022-11-18 15:04:08.613961'
|
||||
updated_at: '2022-11-18 15:04:08.613961'
|
||||
accounting_line_21:
|
||||
id: 21
|
||||
line_type: client
|
||||
journal_code: '530'
|
||||
date: '2022-10-04 13:54:42.975196'
|
||||
account_code: '5801'
|
||||
account_label: Client card
|
||||
analytical_code: ''
|
||||
invoice_id: 5817
|
||||
invoicing_profile_id: 4
|
||||
debit: 1295
|
||||
credit: 0
|
||||
currency: EUR
|
||||
summary: 2210004/VL, shop order
|
||||
created_at: '2022-11-18 15:04:08.622056'
|
||||
updated_at: '2022-11-18 15:04:08.622056'
|
||||
accounting_line_22:
|
||||
id: 22
|
||||
line_type: item
|
||||
journal_code: '530'
|
||||
date: '2022-10-04 13:54:42.975196'
|
||||
account_code: '7067'
|
||||
account_label: Shop order
|
||||
analytical_code:
|
||||
invoice_id: 5817
|
||||
invoicing_profile_id: 4
|
||||
debit: 0
|
||||
credit: 95
|
||||
currency: EUR
|
||||
summary: 2210004/VL, shop order
|
||||
created_at: '2022-11-18 15:04:08.630519'
|
||||
updated_at: '2022-11-18 15:04:08.630519'
|
||||
accounting_line_23:
|
||||
id: 23
|
||||
line_type: item
|
||||
journal_code: '530'
|
||||
date: '2022-10-04 13:54:42.975196'
|
||||
account_code: '7067'
|
||||
account_label: Shop order
|
||||
analytical_code:
|
||||
invoice_id: 5817
|
||||
invoicing_profile_id: 4
|
||||
debit: 0
|
||||
credit: 1200
|
||||
currency: EUR
|
||||
summary: 2210004/VL, shop order
|
||||
created_at: '2022-11-18 15:04:08.640333'
|
||||
updated_at: '2022-11-18 15:04:08.640333'
|
||||
accounting_line_24:
|
||||
id: 24
|
||||
line_type: client
|
||||
journal_code: '530'
|
||||
date: '2022-10-04 14:04:12.742685'
|
||||
account_code: '5801'
|
||||
account_label: Client card
|
||||
analytical_code: ''
|
||||
invoice_id: 5818
|
||||
invoicing_profile_id: 4
|
||||
debit: 1000
|
||||
credit: 0
|
||||
currency: EUR
|
||||
summary: 2210006/VL, shop order
|
||||
created_at: '2022-11-18 15:04:08.656104'
|
||||
updated_at: '2022-11-18 15:04:08.656104'
|
||||
accounting_line_25:
|
||||
id: 25
|
||||
line_type: item
|
||||
journal_code: '530'
|
||||
date: '2022-10-04 14:04:12.742685'
|
||||
account_code: '7067'
|
||||
account_label: Shop order
|
||||
analytical_code:
|
||||
invoice_id: 5818
|
||||
invoicing_profile_id: 4
|
||||
debit: 0
|
||||
credit: 1000
|
||||
currency: EUR
|
||||
summary: 2210006/VL, shop order
|
||||
created_at: '2022-11-18 15:04:08.663862'
|
||||
updated_at: '2022-11-18 15:04:08.663862'
|
||||
accounting_line_26:
|
||||
id: 26
|
||||
line_type: client
|
||||
journal_code: '530'
|
||||
date: '2022-10-04 14:17:52.854636'
|
||||
account_code: '5801'
|
||||
account_label: Client card
|
||||
analytical_code: ''
|
||||
invoice_id: 5819
|
||||
invoicing_profile_id: 4
|
||||
debit: 4002
|
||||
credit: 0
|
||||
currency: EUR
|
||||
summary: 2210008/VL, shop order
|
||||
created_at: '2022-11-18 15:04:08.672150'
|
||||
updated_at: '2022-11-18 15:04:08.672150'
|
||||
accounting_line_27:
|
||||
id: 27
|
||||
line_type: item
|
||||
journal_code: '530'
|
||||
date: '2022-10-04 14:17:52.854636'
|
||||
account_code: '7067'
|
||||
account_label: Shop order
|
||||
analytical_code:
|
||||
invoice_id: 5819
|
||||
invoicing_profile_id: 4
|
||||
debit: 0
|
||||
credit: 2
|
||||
currency: EUR
|
||||
summary: 2210008/VL, shop order
|
||||
created_at: '2022-11-18 15:04:08.680577'
|
||||
updated_at: '2022-11-18 15:04:08.680577'
|
||||
accounting_line_28:
|
||||
id: 28
|
||||
line_type: item
|
||||
journal_code: '530'
|
||||
date: '2022-10-04 14:17:52.854636'
|
||||
account_code: '7067'
|
||||
account_label: Shop order
|
||||
analytical_code:
|
||||
invoice_id: 5819
|
||||
invoicing_profile_id: 4
|
||||
debit: 0
|
||||
credit: 4000
|
||||
currency: EUR
|
||||
summary: 2210008/VL, shop order
|
||||
created_at: '2022-11-18 15:04:08.688864'
|
||||
updated_at: '2022-11-18 15:04:08.688864'
|
||||
accounting_line_29:
|
||||
id: 29
|
||||
line_type: client
|
||||
journal_code: '530'
|
||||
date: '2022-10-04 14:25:37.291945'
|
||||
account_code: '5803'
|
||||
account_label: Client other
|
||||
analytical_code: ''
|
||||
invoice_id: 5820
|
||||
invoicing_profile_id: 3
|
||||
debit: 12000
|
||||
credit: 0
|
||||
currency: EUR
|
||||
summary: 2210010, shop order
|
||||
created_at: '2022-11-18 15:04:08.697635'
|
||||
updated_at: '2022-11-18 15:04:08.697635'
|
||||
accounting_line_30:
|
||||
id: 30
|
||||
line_type: item
|
||||
journal_code: '530'
|
||||
date: '2022-10-04 14:25:37.291945'
|
||||
account_code: '7067'
|
||||
account_label: Shop order
|
||||
analytical_code:
|
||||
invoice_id: 5820
|
||||
invoicing_profile_id: 3
|
||||
debit: 0
|
||||
credit: 12000
|
||||
currency: EUR
|
||||
summary: 2210010, shop order
|
||||
created_at: '2022-11-18 15:04:08.705822'
|
||||
updated_at: '2022-11-18 15:04:08.705822'
|
||||
accounting_line_31:
|
||||
id: 31
|
||||
line_type: client
|
||||
journal_code: '530'
|
||||
date: '2022-10-04 14:32:28.204985'
|
||||
account_code: '5803'
|
||||
account_label: Client other
|
||||
analytical_code: ''
|
||||
invoice_id: 5821
|
||||
invoicing_profile_id: 2
|
||||
debit: 12000
|
||||
credit: 0
|
||||
currency: EUR
|
||||
summary: 2210012, shop order
|
||||
created_at: '2022-11-18 15:04:08.713849'
|
||||
updated_at: '2022-11-18 15:04:08.713849'
|
||||
accounting_line_32:
|
||||
id: 32
|
||||
line_type: item
|
||||
journal_code: '530'
|
||||
date: '2022-10-04 14:32:28.204985'
|
||||
account_code: '7067'
|
||||
account_label: Shop order
|
||||
analytical_code:
|
||||
invoice_id: 5821
|
||||
invoicing_profile_id: 2
|
||||
debit: 0
|
||||
credit: 12000
|
||||
currency: EUR
|
||||
summary: 2210012, shop order
|
||||
created_at: '2022-11-18 15:04:08.722579'
|
||||
updated_at: '2022-11-18 15:04:08.722579'
|
||||
accounting_line_33:
|
||||
id: 33
|
||||
line_type: client
|
||||
journal_code: '530'
|
||||
date: '2022-10-04 14:35:40.584472'
|
||||
account_code: '5803'
|
||||
account_label: Client other
|
||||
analytical_code: ''
|
||||
invoice_id: 5822
|
||||
invoicing_profile_id: 2
|
||||
debit: 3000
|
||||
credit: 0
|
||||
currency: EUR
|
||||
summary: 2210014, shop order
|
||||
created_at: '2022-11-18 15:04:08.731248'
|
||||
updated_at: '2022-11-18 15:04:08.731248'
|
||||
accounting_line_34:
|
||||
id: 34
|
||||
line_type: item
|
||||
journal_code: '530'
|
||||
date: '2022-10-04 14:35:40.584472'
|
||||
account_code: '7067'
|
||||
account_label: Shop order
|
||||
analytical_code:
|
||||
invoice_id: 5822
|
||||
invoicing_profile_id: 2
|
||||
debit: 0
|
||||
credit: 3000
|
||||
currency: EUR
|
||||
summary: 2210014, shop order
|
||||
created_at: '2022-11-18 15:04:08.739474'
|
||||
updated_at: '2022-11-18 15:04:08.739474'
|
@ -168,19 +168,25 @@ class Exports::AccountingExportTest < ActionDispatch::IntegrationTest
|
||||
|
||||
def check_entry_label(invoice, line)
|
||||
if invoice.subscription_invoice?
|
||||
assert_match I18n.t('accounting_export.subscription'),
|
||||
assert_match I18n.t('accounting_summary.subscription_abbreviation'),
|
||||
line[I18n.t('accounting_export.line_label')],
|
||||
'Entry label does not contains the reference to the subscription'
|
||||
end
|
||||
if invoice.main_item.object_type == 'Reservation'
|
||||
assert_match I18n.t("accounting_export.#{invoice.main_item.object.reservable_type}_reservation"),
|
||||
assert_match I18n.t("accounting_summary.#{invoice.main_item.object.reservable_type}_reservation_abbreviation"),
|
||||
line[I18n.t('accounting_export.line_label')],
|
||||
'Entry label does not contains the reference to the reservation'
|
||||
end
|
||||
return unless invoice.main_item.object_type == 'WalletTransaction'
|
||||
if invoice.main_item.object_type == 'WalletTransaction'
|
||||
assert_match I18n.t('accounting_summary.wallet_abbreviation'),
|
||||
line[I18n.t('accounting_export.line_label')],
|
||||
'Entry label does not contains the reference to the wallet'
|
||||
end
|
||||
|
||||
assert_match I18n.t('accounting_export.wallet'),
|
||||
return unless invoice.main_item.object_type == 'OrderItem'
|
||||
|
||||
assert_match I18n.t('accounting_summary.shop_order_abbreviation'),
|
||||
line[I18n.t('accounting_export.line_label')],
|
||||
'Entry label does not contains the reference to the wallet'
|
||||
'Entry label does not contains the reference to the order'
|
||||
end
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user