-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
appendices.tex
1129 lines (900 loc) · 53.4 KB
/
appendices.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
% !TeX spellcheck = en_US
% !TeX encoding = UTF-8
% !TeX root = ledgersmb-book.tex
\part{Appendices}
\label{part-appendices}
\appendix
\chapter{Differences between version 1.2 and 1.3}
\label{app-differences-12-13}
\section{Users}
\label{sec-diff12-13-users}
The way users are defined and used differs greatly between LedgerSMB 1.3 and
older versions. In version 1.3 user access to the database is enforced by the
database itself. This means that users logging in to the LedgerSMB web application
are in reality logging into the PostgreSQL database. In older versions, the web
app would verify the user's credentials (using a common database connection used
for all users).
The difference between these approaches is that security is no longer (solely)
maintained by the web application - with all inherent risks. Instead, the database
now plays an important role as well. The effect is that the LedgerSMB team now
leverages the experience of the PostgreSQL community - a highly respected community
well known for its security focus - to make sure your data stays secure.
This structure also enables LedgerSMB 1.3 to offer separation of duties and
authorizations throughout the application without being required to do a full
rewrite of the application.
It's this shift in paradigm that makes it impossible to meaningfully migrate
users from older LedgerSMB and SQL-Ledger versions to LedgerSMB 1.3.
\chapter{Why deleting invoices is not supported}
\label{app-no-invoice-deletion}
\section{Invoices are debt claims}
\label{sec-no-invoices-deletion-claims}
\section{Cost Of Goods Sold become ambiguous}
\label{sec-no-invoices-deletion-cogs-ambiguity}
From a mail by Chris Travers on the LedgerSMB mailing list:
\begin{quote}
Suppose I buy 10 widgets for \$1 each and then 1 more widget for \$10 each. My FIFO cost queue looks like this:
\$1 \$1 \$1 \$1 \$1 \$1 \$1 \$1 \$1 \$1 \$10
My inventory account shows \$20 in debits and I have credited my AP account to compensate.
I then sell the 11 parts to 11 different people.
The first 10 invoice show a \$1 credit against inventory and a \$1 debit against COGS
The 11th invoice shows a \$10 credit against inventory and a \$10 credit against COGS
and now inventory is down to 0.
Now the 5th customer invoice turns out to be in error. We never shipped this one. The customer never ordered it. it was a data entry error. Translation, we now have one in stock.
If we void the invoice properly, we will reverse the last sale, and put \$10 back in inventory.
If we delete the invoice, we will just remove the \$1 removed. But we don't really know which one was sold and so we de-allocate the \$10 sale.
So now our books are \$9 off of what they should be. They show a balance of \$1 in inventory, and \$19 in cogs. They should show \$10 in each. The worse is still to come however.
Now we sell the item we had in stock. This brings our (empty!) inventory value to -\$9 and our COGS value to \$29. Our books are still \$9 off and we now have impossible, nonsensical values. Delete and re-enter a few more invoices and you can inflate the COGS as far as you'd like. This doesn't work.
Worse, this can't be fixed. You can't make a deletion behave just like a reversal and still keep your books transparent auditability-wise. Even if it could be fixed mathematically (which it can't), there isn't any agreement as to what the proper behavior should be (except 'don't do that'). So it isn't possible to support the workflow "properly" because "properly" can't be defined.
So unless someone can show that the above issues are incorrect, I don't see how we can support deleting invoices after they are posted to the books.
The alternative is the draft/voucher system which is supported in 1.3 for all non-inventory transactions and will be supported for inventory transactions in 1.4. In this system, in the paper world, the clerk fills out a piece of paper with the information that will be entered as an invoice, and this is eventually gets entered and checked by someone else. Both papers are kept in paper systems for reconciliation purposes but typically we tend to assume they are the same (this may be changing and we may be keeping both copies if they are changed in the future). In this model, the voucher is not an invoice. It is simply a piece of paper that represents what will be on the invoice. It is subject to review, and may ultimately be denied.
So in this system we do *not* calculate extrinsic financial movements for documents until they post. This includes COGS. If a draft invoice or invoice voucher is deleted before it is approved it has none of the problems above. Once approved though, it is a part of the permanent record. This guards against data entry errors because a second person can review the data before it is posted (either in bulk or individually). Additionally this guards against theft by ensuring that a single individual cannot individually enter everything necessary to cover for theft, etc.
\end{quote}
\chapter{Installation}
\label{app-installation}
LedgerSMB can be installed on almost any Linux host including Raspberry Pi. The project uses Debian for its docker images and \gls{CI} testing.
The following installation methods are available:
\begin{enumerate}
\item Docker Preview\index{install docker preview} - The recommended way to quickly run and evaluate LedgerSMB.
This method is not suitable for internet facing installations.
\item Docker Production\index{install docker production} - A more secure installation suitable as a base for internet facing use.
\item Native\index{install native} - A more complex installation that requires detailed knowledge of the underlying operation system.
The project does NOT recommend this installation method.
\item Docker Development\index{install development} - Used by developers and includes extra libraries and code.
Not recommended unless developing code for LSMB.
\item Linux Distribution\index{install distribution} - Some distributions have old versions of LedgerSMB. With recent LSMB improvements, the LSMB project no longer fits into the distribution's guidelines.
The consequence is that distributions are no longer updated or maintained.
The project does not recommend using LSMB from any Linux distribution.
\end{enumerate}
\section{Docker preview}
\label{sec-installation-docker-preview}
The advantage of using docker preview is that all prerequisites are determined and loaded automatically.
This is the quickest way to preview LedgerSMB.
This method should NOT be used to install LSMB in a manner that allows internet wide connections.
On Ubuntu 22.04 use the following commands:
\begin{lstlisting}[language=bash, basicstyle=\ttfamily, breaklines=true,frame=none,backgroundcolor=\color{ghostwhite}]
# Install docker compose
sudo apt install docker-compose
# Make sure user is in the docker group
sudo usermod -a -G docker $USER
# Get the latest version of LSMB 1.11
wget https://raw.githubusercontent.com/ledgersmb/ledgersmb-docker/1.11/docker-compose.yml
# Update the group credentials
exec su -l $USER
# Start the container not using sudo
docker-compose up -d
\end{lstlisting}
For the authoritative installation source see \url{https://github.com/ledgersmb/LedgerSMB/blob/master/README.md}
\section{Docker Production}
\label{sec-installation-docker-production}
See \url{https://github.com/ledgersmb/ledgersmb-docker?tab=readme-ov-file#docker-compose-with-reverse-proxy} for the installation instructions.
\section{Native}
\label{sec-installation-native}
LedgerSMB provides installation tarballs for installing LSMB into the native file system.
This installation method requires experience and detailed knowledge of both the Linux operating system and LedgerSMB.
Experience has shown that getting prerequisites and security correct is sometimes a significant challenge.
The following commands were tested on a clean, default, server install with no snaps using \texttt{ubuntu-22.04.3-live-server-amd64.iso}.
The steps were extracted from the docker install at \url{https://github.com/ledgersmb/ledgersmb-docker/blob/1.11/Dockerfile}.
This docker file should be considered the authoritative source.
\vspace{5mm}
\begin{center}
\large{Warning}
\large{The following commands need to be modified for proper security, which is the responsibility of the installer.}
\end{center}
\vspace{5mm}
Make sure Ubuntu is up to date:
\begin{lstlisting}[language=sh, basicstyle=\small\ttfamily, breaklines=true,frame=none,backgroundcolor=\color{ghostwhite}]
sudo apt update
sudo apt -y upgrade
sudo reboot
\end{lstlisting}
Install the prerequisites:
\begin{lstlisting}[language=bash, basicstyle=\small\ttfamily, breaklines=true,frame=none,backgroundcolor=\color{ghostwhite},showstringspaces=false]
#!/bin/bash
#
# The following commands show an example of the commands
# that may be used for a native install.
#
# They have a number of shortcomings that an experienced
# Linux administrator should recognize and correct.
#
# For example, PostgreSQL is, by default, installed
# and running as a superuser and should not be.
#
set -e # stop on error
set -x # echo commands
sudo apt-get -y install \
cpanminus \
make \
gcc \
libperl-dev \
wget ca-certificates \
gnupg \
iproute2 \
libclass-c3-xs-perl \
texlive-plain-generic \
texlive-latex-recommended \
texlive-fonts-recommended \
texlive-xetex fonts-liberation \
lsb-release \
dh-make-perl \
libmodule-cpanfile-perl \
git \
wget
sudo apt-file update
# Another viable location is /usr/local/ledgersmb/
export INSTALL_LOCATION="/srv"
export LSMB_VERSION="1.11.8"
export LSMB_DL_DIR="Releases"
export ARTIFACT_LOCATION="https://download.ledgersmb.org/f/$LSMB_DL_DIR/$LSMB_VERSION/ledgersmb-$LSMB_VERSION.tar.gz"
wget --quiet -O /tmp/ledgersmb-$LSMB_VERSION.tar.gz \
"$ARTIFACT_LOCATION"
sudo tar -xzf /tmp/ledgersmb-$LSMB_VERSION.tar.gz \
--directory "$INSTALL_LOCATION"
rm -f /tmp/ledgersmb-$LSMB_VERSION.tar.gz
cd ${INSTALL_LOCATION}/ledgersmb
gather () {
for lib in $(cpanfile-dump --with-all-features --recommends --no-configure --no-build --no-test)
do
if dh-make-perl locate "$lib" 2>/dev/null ;
then
:
else
echo no : $lib ;
fi ;
done
}
gather | grep -v dh-make-perl | \
grep -v 'not found' | \
grep -vi 'is in Perl ' | \
cut -d' ' -f4 | \
sort | \
uniq | \
sudo tee ${INSTALL_LOCATION}/derived-deps
sudo apt-get -y install $(cat ${INSTALL_LOCATION}/derived-deps)
sudo cpanm --quiet --notest \
--with-feature=starman \
--with-feature=latex-pdf-ps \
--installdeps ${INSTALL_LOCATION}/ledgersmb/
# Postgres
# From https://www.postgresql.org/download/linux/ubuntu/
sudo sh \
-c 'echo "deb https://apt.postgresql.org/pub/repos/apt \
$(lsb_release -cs)-pgdg main" \
> /etc/apt/sources.list.d/pgdg.list'
wget --quiet -O \
- https://www.postgresql.org/media/keys/ACCC4CF8.asc | \
sudo apt-key add -
sudo apt-get -y update
# Warning: Actually using the default PG install is NOT best practice.
sudo apt-get -y install postgresql
# Optional clean up
# sudo apt-get purge -y git cpanminus \
# make gcc libperl-dev
# sudo apt-get autoremove -y
# sudo apt-get clean
\end{lstlisting}
Once all of the prerequisites have been installed the user can proceed by following the install instructions on the web site.
For example, \url{https://ledgersmb.org/content/installing-ledgersmb-111}, starting at "Configuring the PostgreSQL server"
\section{Docker Development}
\label{sec-installation-docker-development}
See \url{https://github.com/ledgersmb/ledgersmb-dev-docker/blob/master/README.md} for the installation instructions.
\section{Linux Distribution}
\label{sec-installation-linux-distribution}
This method of installation is not recommended. These old distributions only exist to support existing users that have not yet upgraded.
\chapter{Migration}
\label{app-migration}
\section{Introduction}
\label{sec-migration-introduction}
There are plenty of reasons to want to migrate to LedgerSMB 1.3:
\begin{enumerate}
\item Separation of duties
\item Security better integrated into the application
\item Better, more strict data model
\label{item:StricterDataModel}
\item Some important sources of user error eliminated
\item Better workflows for cash reconciliation
\item @@@ others?
\end{enumerate}
Yet, while item \ref{item:StricterDataModel} is a good reason to want to switch, it's
also a reason why migration from older versions to 1.3 can be harder than earlier
migrations: when the data
in your older version is not consistent, it won't fit into the new data model and
will need to be fixed first.
Especially if your database has a very long line of history, being migrated through
lots of SQL-Ledger and LedgerSMB versions, you may want to consider asking for help
from a professional party. It could save you a lot of time.
However, don't be discouraged and have a go yourself first. Just be sure to run
your upgrade on a backup database: the migration process is non-destructive, but
in case accounting data is involved: better safe than sorry!
Also it is worth noting that a number of automatic checks are performed on your
data prior to migration, and to the extent possible, you are given an
opportunity to fix those issues identified. Because these checks are
pre-migration checks, they are written to your old data and will persist after
backing out of a migration to 1.3.
\section{From older LedgerSMB versions}
\label{sec-migration-from-older-ledgersmb}
\section{From SQL-Ledger 2.8}
\label{sec-migration-from-sql-ledger-28}
\section{From older SQL-Ledger versions}
\label{sec-migration-from-older-sql-ledger}
\section{From other accounting packages}
\label{sec-migration-from-other-accounting-systems}
\subsection{Overview}
While accounting and ERP solution have wildly differing structures to record their
data, this sections uses data with a relatively simple structure as a show case of
how this problem may be dealt with.
\begin{quote}
Note that the encoding you use to transfer to the database depends on the settings
used to create the PostgreSQL database with. A migration is a good moment to think
about encodings an solve older encoding issues. Now would be a good moment to
anticipate the requirement for accented characters and non-western alphabets: set up
a UTF-8 encoded database and recode your data accordingly.
\end{quote}
\subsection{Migrating customers}
\label{subsec-migration-others-customers}
The source system for this section uses a structure where every company has one
contact person, one address, one phone number and e-mail.
In order to understand how to migrate this data structure to LedgerSMB, it's
important to understand that:
\begin{enumerate}
\item The company from the source maps to the \emph{Company} and \emph{Entity} entities
\item The contact person maps to the \emph{Entity Credit Account} entity
\item The address maps to the \emph{Location} entity - and requires a location class: Sales, Billing or Shipping
\item The phone number, fax number and e-mail map to \emph{Contact items}
\end{enumerate}
The reason behind the separation between the \emph{Company} and \emph{Entity} entities
is that every customer is an \emph{Entity}, but not all entities are companies, since
some entities are \emph{Person}s - natural persons.
@@@ How to
\subsection{Migrating parts, services, ...}
\label{subsec-migration-others-products}
\subsection{Migrating the balance}
\label{subsec-migration-others-balance}
The strategy that I used when migrating to LedgerSMB is the following:
\begin{itemize}
\item create customers and vendors as needed
\item create at least the parts and services for which there are open AR or AP items in the closing balance
\item create the open AR/AP items in the closing balance by posting them on the original opening date (this allows you to do your aging management in LSMB from day 1)
\item create in addition the parts for which you have stock in the closing balance
\item import your stock by posting invoices against the inventory entity
\item make sure you "pay" the invoices - e.g. by paying them from equity
\item draw up the incomplete balance you have so far
\item calculate the delta of the partially imported balance against the closing balance
\item import the delta balance on top of what you already had to make a full balance
\end{itemize}
What I did is post the transaction from the last step on the day before I wanted to start my books; say you want to start your books on 2014-01-01, then you'd post it on 2013-12-31. That way, the opening balance of your books on the starting date is exactly what you had on the closing balance of the books you left behind.
\subsubsection{Migrating open AR and AP items}
\label{subsec-migration-others-open-items}
\subsubsection{Migrating your ledger}
\label{subsec-migration-others-ledger}
\section{Migrating between PostgreSQL versions}
\label{sec-migration-postrgesql}
There are generally 2 ways to upgrade PostgreSQL\index{PostgreSQL upgrade} that apply to normal LSMB installations.
Both are described in the current PostgreSQL documentation at \url{https://www.postgresql.org/docs/current/index.html}.
\begin{enumerate}
\item Dump\index{dump} and restore\index{restore} -
Described in more detail below.
Note that the roles must be restored before database creation and the data restore.
\item Upgrade in place using \texttt{pg\_upgrade}\index{pg\_upgrade} - When doing an upgrade in place, there are no specific LedgerSMB requirements.
Beware, upgrade in place requires both versions of the PostgreSQL to be installed and working. It is therefore more complex.
\end{enumerate}
LedgerSMB versions prior to version 1.9.16 did not support PostgreSQL 14 or higher due to a backward incompatible change in PostgreSQL 14.
Best practice in this situation is to update to at least LSMB 1.10. prior to upgrading to any version of PostgreSQL 14 or higher.
The following upgrade procedure uses \texttt{lsmb\_dbadmin}\index{lsmb\_dbadmin} for the database administrative user.\footnote{Default LedgerSMB installations do not automatically create an \texttt{lsmb\_dbadmin} user. This user is created manually during the initial database installation. For an example see, \url{https://ledgersmb.org/index.php/content/installing-ledgersmb-111}.}
But if the original database installation did not follow the recommended installation practice, then the \texttt{postgres} superuser may have to be used. Using the \texttt{postgres} superuser is not considered best practice.
The following upgrade procedure should not be used when upgrading a cloud provided PostgreSQL installation.
In this case, the cloud provider's instructions have to be consulted to determine the proper upgrade procedure.
The upgrade procedure when using dump and restore with a local LSMB native or docker installation is:
\begin{enumerate}
\item Stop users from accessing the current LSMB installation and make sure all users are logged off.
The instructions for this step vary depending on how LSMB was installed.
Note that access to \texttt{setup.pl} will be needed to create backups.
\item Make sure the current LedgerSMB installation is using the latest version.
If not, see the \secref{sec-migration-from-older-ledgersmb} for instructions on upgrading LSMB.
\item Make a dump of both the roles and data using \texttt{setup.pl}.
\item Inspect the backup to make sure it is complete.
Ideally, this inspection would include restoring the backup to temporary LedgerSMB installation with the same versions as the existing installation.
Then make sure it is complete by logging into the temporary LedgerSMB installation and inspecting reports, accounts, etc.
Do not proceed unless you are sure your backups can be restored completely and accurately.
\item Create a new LedgerSMB installation with the new version PostgreSQL.
The instructions for a new install are at \url{https://ledgersmb.org/installation}\index{installation}.
\item The next 3 restore steps, using \texttt{psql}, came from \url{https://ledgersmb.org/faq/how-do-i-restore-my-data}\index{faq database restore}\index{database restore}, which these instructions supersede.
Other restore tools might work, but they have not been tested.
\item Restore the "roles" backup. The \texttt{psql} syntax is:
\texttt{\$ psql -h [database host] -U [database admin user] < [roles backup file]}
For example:
\texttt{\$ psql -h localhost -U lsmb\_dbadmin < lsmb-roles.sqlc}
\item Create a new database.
The database name is usually very similar to the company name.
Do not create the database using \texttt{setup.pl} as that creates the company structure inside the database, which will interfere with the restore. The \texttt{psql} syntax is:
\texttt{\$ psql -h [database host] -U [database admin user] -c 'CREATE DATABASE [new company name]'}
For example:
\texttt{\$ psql -h localhost -U lsmb\_dbadmin -c 'CREATE DATABASE newcompany'}
\item Restore the "data" backup. The \texttt{psql} syntax is:
\texttt{\$ psql -h [database host] -U [database admin user] [new company name] < [company backup file]}
For example:
\texttt{\$ psql -h localhost -U lsmb\_dbadmin newcompany < lsmb-db.sqlc}
\item Read the beginning section of the PostgreSQL release notes for each PostgreSQL version from the old to the new and determine
if there are any additional steps that must be performed on the database after the restore.
If there are, do them now.
\item Verify all data restored and that LedgerSMB is working correctly.
\item Replace the old LSMB installation with the new installation.
The exact steps to accomplish this varies based on how LSMB was originally installed.
\item Allow users to use LSMB.
\end{enumerate}
\subsection{Notes on migration from PostgreSQL 8.3 (or earlier) to 8.4 - deprecated }
\label{subsec-migration-pre84-to84plus}
\vspace{5mm}
\begin{center}
\large{The content of this sub-section is deprecated, unedited, and only remains for historical reference purposes.}
\end{center}
\vspace{5mm}
Performance benefit due to built in support for recursive queries only available
after the next setup.pl run
Also, after next setup.pl run, one should uninstall the tablefunc extension
In 9.1+ may need to \texttt{DROP EXTENSION tablefunc;}.
In 8.4, to 9.0 may need to \texttt{uninstall\_tablefunc.sql} from the PostgreSQL contrib directory.
LedgerSMB 1.3 uses some extension modules for versions PostgreSQL 8.3 and before for functionality
that has been built into PostgreSQL 8.4 and later. To make use of the (faster) built in version
of that functionality, the following restore procedure should be used.
\begin{enumerate}
\item Migrate the database to the new function as described in section
\item If you're using 9.1 and up, issue the command ``CREATE EXTENSION tablefunc FROM UNPACKAGED''
from a psql prompt when connected to the company database
\item Run 'setup.pl' from your browser to upgrade the database's routines; this command will
install routines optimized for your version of PostgreSQL
\item To clean up functions and procedures in the database which are no longer used you may need to run one of the commands below:
\begin{description}
\item [8.4 or 9.0] \texttt{psql ... -f uninstall\_tablefunc.sql} in a shell
\item [9.1 to 9.5] \texttt{DROP EXTENSION tablefunc;} from a psql session connected to the company database
\end{description}
\end{enumerate}
\chapter{Listing of application roles}
\label{app-role-listing}
Application roles \index{roles} specify the right (privilege) to execute one or more tasks in the application.
LedgerSMB enforces these roles by allowing a user to select (list, read) data from or to
insert (create), update (edit) or delete (delete) data in the tables holding the data
related to the execution of these tasks.
%This list contains workaround for HTML lists that looks so bad. That is all of the '\htmlspacing' stuff.
% This change at least haromonizes the look between PDF and HTML except that
% PDF does not have a line space between the role and the description and the HTML does.
% I am looking for a better solution before we go about modifying all of the lists in the book. Neil
% For large groups of roles both the first and last items are indexed in case the list appears in separate pages.
\ifpdf
\newcommand{\htmlspacing}{}
\else
\newcommand{\htmlspacing}{ \hfill \\}
\fi
These roles definitions are generated directly from a running database using \texttt{gather-db-info.pl}.
\input{auto-generated/role_list_appendex.tex}
\chapter{Deprecated Content}
\label{app-deprecated-content}
\section{ledgersmb.conf}
\label{app-deprecated-ledgersmb-conf}
The use of \texttt{ledgersmb.conf} \index{ledgersmb.conf} is deprecated as of 1 Jan 2023 in favor of \texttt{ledgersmb.yaml} \index{ledgersmb.yaml} and only remains here for historical reasons.
The environment variable for controlling the configuration is \texttt{LSMB\_CONFIG\_FILE}\index{LSMB\_CONFIG\_FILE}.
By default \texttt{LSMB\_CONFIG\_FILE} points to \texttt{/etc/ledgersmb/ledgersmb.conf} and can be set to an alternate location.
\subsubsection{[main] Section}
\label{subsubsec-global-config-ledgersmb-conf-general}
\begin{description}
\item[language] Set language for login and admin pages.
\item[date\_format] Set the date format for the admin pages. The default is \texttt{yyyy-mm-dd}. Unset means detected from the browser)
\item[log\_level] Specifies the logging level to be used. This setting is ignored when the \texttt{log\_config} setting
is supplied and indicates an existing file. Available values are OFF, FATAL, ERROR, WARN, INFO, DEBUG, TRACE.
\item [log\_config] Set the name of the extended logging configuration file. This file uses the \texttt{log4j/Log::Log4perl} syntax described at \url{https://metacpan.org/pod/Log::Log4perl#Configuration-files}
\item [dojo\_theme] This is the Dojo theme that is used by default when no other theme
has been selected. The default if unset is \texttt{claro}. Other values can be \texttt{nihilo}, \texttt{soria}, and \texttt{tundra}.
\item[auth] Indicates which authentication module is to be used; default is DB, referring to LedgerSMB::Auth::DB.
\item[cache\_templates] Determines if HTML templates used for the LedgerSMB UI will be stored
in precompiled form for improved performance. The value 0 (zero) means no caching; the value
1 means caching in the directory \$(tempdir)/lsmb\_templates; systems running multiple
LedgerSMB instances with customized UIs should use separate values for {\tt tempdir} for that
reason
% From the old book, commented out for now.
% \item[check\_max\_invoices] @@@TODO
% \item[max\_post\_size] States the maximum size in bytes of the body in case of a POST request; this
% setting reduces the impact of DoS requests, if the system is under attack. The setting also limits the
% maximum size of attachments (see \secref{sec-workflows-quotations-file-attachments}) that can be uploaded
% \item[decimal\_places] @@@TODO
% \item[cookie\_name] @@@TODO
% \item[no\_db\_str] @@@TODO
\end{description}
\subsubsection{[environment] Section}
\label{subsubsec-global-config-ledgersmb-conf-environment}
Sets shell environment variables when starting up.
\begin{description}
\item[PATH] If the server can't find applications, append to the path. For example:
\texttt{PATH=/bin:/usr/bin:/usr/local/bin:/usr/local/pgsql/bin}
\item [PERL5LIB] On some operating systems like macOS the perl path may need to be set. For example, on macOS using Fink's Perl libs it might be set like:
\texttt{PERL5LIB=/sw/lib/perl5}
\end{description}
\subsubsection{[paths] Section}
\label{subsubsec-global-config-ledgersmb-conf-paths}
\begin{description}
\item [templates] Templates base directory. Typically set to \texttt{templates}.
\item [images] Images base directory. Typically set to \texttt{UI/images}.
\item [localepath] Path to locale files. Defaults to \texttt{locale/po}.
\item [templates\_cache] Location where compiled templates are stored. When relative, appended to the directory specified by \texttt{File::Spec->tmpdir()}.
Defaults to \texttt{lsmb\_templates}.
\item [workflows] Directory where workflow files are stored. Defaults to \texttt{workflows}
\item [custom\_workflows] Directory where custom workflow files are stored. Custom workflows are used to override behavior of the default workflows by providing actions, conditions, etc. with the same name and type or by providing workflows of the same type with additional states and actions. Defaults to \texttt{custom\_workflows}.
% Items from the old book
% \item [spool] @@@TODO
\end{description}
\subsubsection{[programs] Section}
\label{subsubsec-global-config-ledgersmb-conf-programs}
Setup the various helper programs that can be used with LedgerSMB.
\subsubsection{[mail] Section}
\label{subsubsec-global-config-ledgersmb-conf-mail}
\begin{description}
\item [smtphost] The host name of the smtp\index{smtp} server. If provided, then do not use local sendmail. Note that one of sendmail or smtphost has to be provided for email to work.
\item [sendmail] Path the local sendmail executable. If provided then do not use an smtp server. Note that one of sendmail or smtphost has to be provided for email to work.
\item [smtpport] The port number of the smtp server. Note this might vary depending on whether TLS or SSL is used.
\item [smtpuser] The smpt server account name
\item [smtpauthmech] The smtp server authentication method
\item [smtppass] The smtp server password
\item [backup\_email\_from] Set to enable e-mail delivery of backups. For example:
\texttt{backup\_email\_from = backups@lsmb\_hosting.com}
\item [smtptimeout] The timeout value in seconds.
% Not sure this is correct. Why use tls to get SSL? But this appears to be the way the code currently works.
\item [smtptls] If unset or 'no' then do not use either TLS or SSL. If 'yes' then use TLS and if 'tls' use SSL for the smtp connection.
\item [smtpsender\_hostname] Override the default host name for \texttt{helo}.
\end{description}
\subsubsection{[printers] Section}
\label{subsubsec-global-config-ledgersmb-conf-printers}
This section contains a list of printers and the commands
to be executed in order for the output to be sent to the given printer with
the document to be printed fed to the program through standard input.
The example below shows how to send standard input data to a printer called ``laser''
when selecting the item ``Laser'' in the LedgerSMB printer selection drop down.
\texttt{
Laser = lpr -Plaser
}
Or to an Epson Printer.
\texttt{
Epson = lpr -PEpson
}
\subsubsection{[database] Section}
\label{subsubsec-global-config-ledgersmb-conf-database}
\begin{description}
\item [host] Name of the host to connect to. See the documentation of the {\tt -h} command line option at
\url{https://www.postgresql.org/docs/current/static/app-psql.html}
for more information (documentation unchanged since before 8.3, so applies to older versions as well)
\item [port] Port number to be used to connect to. See the documentation of the {\tt -p} option at the
same URL as the previous item
\item [default\_db] Database to connect to when the ``Company'' entry field in the login screen is left blank
\item [db\_namespace] The name space the company resides in; expert setting -- should not be used (default is
``public'')
\item [sslmode] Selects whether to use \gls{SSL} over TCP connections or not; can be ``require'', ``allow'',
``prefer'' or ``disable''. Default is ``prefer''.
\end{description}
\chapter{Open source explained}
\label{app-open-source-explained}
\section{An open source application}
\label{sec-open-source-application}
\section{An open source book}
\label{sec-open-source-book}
\chapter{Project history}
\label{cha-ledgersmb-history}
%% @@@TODO This section should be entirely rewritten from the perspective of 1.10
The project started out as a fork of \gls{SL} - the open source \gls{erp}
developed by Dieter Simader - somewhere between SQL-Ledger versions 2.6
and 2.8. A fork happens when a group of developers can't - for whatever
reason - continue to work as one group on a project. At that time, the
project splits into two or more projects and the fork is in effect.
LedgerSMB split off from the SQL-Ledger project (i.e. forked) because
there was disagreement between developers about how to go forward both with
respect to handling of security vulnerability reports as well as the general
state of the code base.
After the fork, between versions 1.0 and 1.2 most energy was spent on
making LedgerSMB more secure (i.e. less vulnerable to security attacks). In
technical terms, measures were taken to fend off (amongst other things):
\begin{itemize}
\item Cross site scripting attacks
\item Replay attacks
\item SQL injection attacks
\end{itemize}
Come version 1.3 the development directed toward improvement of the overall
quality of the code base as the old \acrshort{SL} code was in very poor state:
looking very much like web programs as they were written in 1998, the code had
grown largely outdated in style and was no longer maintainable by 2007.
The 1.3 effort focused on bringing relief with a new application structure.
Modern and important features were realized: separation of duties (for the
accounting part of the application) and authorizations to allow distinguishing
different roles in a company.
Unfortunately, by the beginning of 2011 the project looked mostly dead from
an outside perspective: the team had not brought forward any releases since
2007, there were no signs of development and the mailing lists (a measure
of community activity) were
completely silent. \gls{svn} commits were continuing, but were being made by
ever fewer committers and contributors.
Fortunately development activity was increasing in the first half year of 2011,
leading to the release of version 1.3 by September. Between September and the
year end in total 10 small bug fixes were released, showing active commitment
of the developers to maintain the application.
New committers showed up, indicating revived community interest. Other signs of
increased interest are the higher number of bug reports and the creation of the
Linux package for Debian 7, which has been included in Ubuntu 12.04 as of
October 2012.
\chapter{Copyright and license}
\label{app-copyright-license}
Copyright (c) 2011, 2012 Erik H\"ulsmann.
This work is licensed under the Creative Commons Attribution License.
To view a copy of this license, visit \url{https://creativecommons.org/licenses/by/3.0/}
or send a letter to Creative Commons, 559 Nathan Abbott Way,
Stanford, California 94305, USA.
A summary of the license is given below, followed by the full legal text.
\section{License summary}
\label{sec-license-summary}
\begin{verbatim}
You are free:
* to share -- to copy, distribute and transmit the work
* to remix -- to adapt the work
Under the following condition:
You must attribute the work in the manner specified by
the author or licensor (but in a way that suggests that
they endorse you or your use of the work).
With the understanding that:
Waiver -- Any of the above conditions can be waived if
you get permission from the copyright holder.
Other rights -- In no way are any of the following
rights affected by the license:
* Your fair dealing or fair use rights, or other
applicable copyright exceptions and limitations;
* The author's moral rights;
* Rights other persons may have either in the work
itself or in how the work is used, such as
publicity or privacy rights.
\end{verbatim}
\section{Legal full text}
\label{sec-license-fulltext}
\begin{verbatim}
License
THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS
OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR
"LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR
OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS
AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS
PROHIBITED.
BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU
ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS
LICENSE. TO THE EXTENT THIS LICENSE MAY BE CONSIDERED TO
BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS
CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF
SUCH TERMS AND CONDITIONS.
1. Definitions
"Adaptation" means a work based upon the Work, or upon
the Work and other pre-existing works, such as a
translation, adaptation, derivative work, arrangement of
music or other alterations of a literary or artistic
work, or phonogram or performance and includes cinemato-
graphic adaptations or any other form in which the Work
may be recast, transformed, or adapted including in any
form recognizably derived from the original, except that
a work that constitutes a Collection will not be
considered an Adaptation for the purpose of this License.
For the avoidance of doubt, where the Work is a musical
work, performance or phonogram, the synchronization of
the Work in timed-relation with a moving image
("synching") will be considered an Adaptation for the
purpose of this License.
"Collection" means a collection of literary or artistic
works, such as encyclopedias and anthologies, or
performances, phonograms or broadcasts, or other works or
subject matter other than works listed in Section 1(f)
below, which, by reason of the selection and arrangement
of their contents, constitute intellectual creations, in
which the Work is included in its entirety in unmodified
form along with one or more other contributions, each
constituting separate and independent works in
themselves, which together are assembled into a
collective whole. A work that constitutes a Collection
will not be considered an Adaptation (as defined above)
for the purposes of this License.
"Distribute" means to make available to the public the
original and copies of the Work or Adaptation, as
appropriate, through sale or other transfer of ownership.
"Licensor" means the individual, individuals, entity or
entities that offer(s) the Work under the terms of this
License.
"Original Author" means, in the case of a literary or
artistic work, the individual, individuals, entity or
entities who created the Work or if no individual or
entity can be identified, the publisher; and in addition
(i) in the case of a performance the actors, singers,
musicians, dancers, and other persons who act, sing,
deliver, declaim, play in, interpret or otherwise perform
literary or artistic works or expressions of folklore;
(ii) in the case of a phonogram the producer being the
person or legal entity who first fixes the sounds of a
performance or other sounds; and,
(iii) in the case of broadcasts, the organization that
transmits the broadcast.
"Work" means the literary and/or artistic work offered
under the terms of this License including without
limitation any production in the literary, scientific
and artistic domain, whatever may be the mode or form
of its expression including digital form, such as a
book, pamphlet and other writing; a lecture, address,
sermon or other work of the same nature; a dramatic or
dramatico-musical work; a choreographic work or
entertainment in dumb show; a musical composition with
or without words; a cinematographic work to which are
assimilated works expressed by a process analogous to
cinematography; a work of drawing, painting,
architecture, sculpture, engraving or lithography; a
photographic work to which are assimilated works
expressed by a process analogous to photography; a work
of applied art; an illustration, map, plan, sketch or
three-dimensional work relative to geography, topography,
architecture or science; a performance; a broadcast; a
phonogram; a compilation of data to the extent it is
protected as a copyrightable work; or a work performed
by a variety or circus performer to the extent it is not
otherwise considered a literary or artistic work.
"You" means an individual or entity exercising rights
under this License who has not previously violated the
terms of this License with respect to the Work, or who
has received express permission from the Licensor to
exercise rights under this License despite a previous
violation.
"Publicly Perform" means to perform public recitations
of the Work and to communicate to the public those public
recitations, by any means or process, including by wire
or wireless means or public digital performances; to make
available to the public Works in such a way that members
of the public may access these Works from a place and at
a place individually chosen by them; to perform the Work
to the public by any means or process and the
communication to the public of the performances of the
Work, including by public digital performance; to
broadcast and rebroadcast the Work by any means including
signs, sounds or images.
"Reproduce" means to make copies of the Work by any means
including without limitation by sound or visual
recordings and the right of fixation and reproducing
fixations of the Work, including storage of a protected
performance or phonogram in digital form or other
electronic medium.
2. Fair Dealing Rights. Nothing in this License is
intended to reduce, limit, or restrict any uses free
from copyright or rights arising from limitations or
exceptions that are provided for in connection with the
copyright protection under copyright law or other
applicable laws.
3. License Grant. Subject to the terms and conditions of
this License, Licensor hereby grants You a worldwide,
royalty-free, non-exclusive, perpetual (for the duration
of the applicable copyright) license to exercise the
rights in the Work as stated below:
to Reproduce the Work, to incorporate the Work into one
or more Collections, and to Reproduce the Work as
incorporated in the Collections;
to create and Reproduce Adaptations provided that any
such Adaptation, including any translation in any medium,
takes reasonable steps to clearly label, demarcate or
otherwise identify that changes were made to the original
Work. For example, a translation could be marked "The
original work was translated from English to Spanish,"
or a modification could indicate "The original work has
been modified.";
to Distribute and Publicly Perform the Work including as
incorporated in Collections; and, to Distribute and
Publicly Perform Adaptations.
For the avoidance of doubt:
Non-waivable Compulsory License Schemes. In those
jurisdictions in which the right to collect royalties
through any statutory or compulsory licensing scheme
cannot be waived, the Licensor reserves the exclusive
right to collect such royalties for any exercise by You
of the rights granted under this License; Waivable
Compulsory License Schemes. In those jurisdictions in
which the right to collect royalties through any
statutory or compulsory licensing scheme can be waived,
the Licensor waives the exclusive right to collect such
royalties for any exercise by You of the rights granted
under this License; and, Voluntary License Schemes.
The Licensor waives the right to collect royalties,
whether individually or, in the event that the Licensor
is a member of a collecting society that administers
voluntary licensing schemes, via that society, from any
exercise by You of the rights granted under this License.
The above rights may be exercised in all media and
formats whether now known or hereafter devised. The
above rights include the right to make such modifications
as are technically necessary to exercise the rights in
other media and formats. Subject to Section 8(f), all
rights not expressly granted by Licensor are hereby
reserved.
4. Restrictions. The license granted in Section 3 above
is expressly made subject to and limited by the
following restrictions:
You may Distribute or Publicly Perform the Work only
under the terms of this License. You must include a copy
of, or the Uniform Resource Identifier (URI) for, this
License with every copy of the Work You Distribute or
Publicly Perform. You may not offer or impose any terms
on the Work that restrict the terms of this License or
the ability of the recipient of the Work to exercise the
rights granted to that recipient under the terms of the
License. You may not sublicense the Work. You must keep
intact all notices that refer to this License and to the
disclaimer of warranties with every copy of the Work You
Distribute or Publicly Perform. When You Distribute or
Publicly Perform the Work, You may not impose any
effective technological measures on the Work that
restrict the ability of a recipient of the Work from You
to exercise the rights granted to that recipient under
the terms of the License. This Section 4(a) applies to
the Work as incorporated in a Collection, but this does
not require the Collection apart from the Work itself to
be made subject to the terms of this License. If You
create a Collection, upon notice from any Licensor You
must, to the extent practicable, remove from the
Collection any credit as required by Section 4(b), as
requested. If You create an Adaptation, upon notice from
any Licensor You must, to the extent practicable, remove
from the Adaptation any credit as required by
Section 4(b), as requested.
If You Distribute, or Publicly Perform the Work or any
Adaptations or Collections, You must, unless a request
has been made pursuant to Section 4(a), keep intact all
copyright notices for the Work and provide, reasonable
to the medium or means You are utilizing: (i) the name
of the Original Author (or pseudonym, if applicable) if
supplied, and/or if the Original Author and/or Licensor
designate another party or parties (e.g., a sponsor
institute, publishing entity, journal) for attribution
("Attribution Parties") in Licensor's copyright notice,
terms of service or by other reasonable means, the name
of such party or parties; (ii) the title of the Work if
supplied; (iii) to the extent reasonably practicable,
the URI, if any, that Licensor specifies to be associated
with the Work, unless such URI does not refer to the
copyright notice or licensing information for the Work;
and (iv), consistent with Section 3(b), in the case of an
Adaptation, a credit identifying the use of the Work in
the Adaptation (e.g., "French translation of the Work by
Original Author," or "Screenplay based on original Work
by Original Author"). The credit required by this
Section 4 (b) may be implemented in any reasonable
manner; provided, however, that in the case of a