Giter VIP home page Giter VIP logo

ledgersmb / ledgersmb Goto Github PK

View Code? Open in Web Editor NEW
392.0 47.0 149.0 236.48 MB

Double-entry accounting & ERP for the web

Home Page: https://ledgersmb.org

License: Other

Perl 55.29% HTML 12.19% CSS 1.70% JavaScript 5.27% TeX 1.39% Shell 0.26% PLpgSQL 21.21% Makefile 0.11% Gherkin 1.81% Gnuplot 0.01% Vue 0.77%
postgresql accounting erp billing web-app quotations orders projects inventory-management inventory fixed-asset invoicing material-cards time-tracking payments purchasing manufacturing double-entry-accounting bookkeeping general-ledger

ledgersmb's Introduction

LedgerSMB

Small and Medium business accounting and ERP

CII Best Practices CI CodeQL GPLv2 Licence Coverage Status Docker Mentioned in Awesome <awesome-selfhosted>

Content

  1. Description
  2. System requirements
  3. Quick start
  4. Project information
  5. Copyright
  6. License

Description

LedgerSMB is a free web-based double-entry accounting system, featuring quotation, ordering, invoicing, projects, timecards, inventory management, shipping and more ...

Directly send orders and invoices from the built-in e-mail function to your customers or RFQs (request for quotation) to your vendors with PDF attachments, from anywhere in the world with the browser-based UI.

With its data stored in the enterprise-strength PostgreSQL open source database system, the system is known to operate smoothly for businesses with thousands of transactions per week.

Customer visible output is fully customizable in templates, allowing easy and fast customization. Supported output formats are PDF, CSV, HTML, ODF and more.

System requirements

Note that these are the system requirements for LedgerSMB 1.12.0-dev, the current development version. Please check the system requirements for the 1.11 stable version and the 1.10 'old stable' version.

Server

  • Perl 5.36+
  • PostgreSQL 13+
  • Web server (e.g. nginx, Apache HTTPd, lighttpd, Varnish)

The web server is only required for production installs; for evaluation purposes a simpler setup can be used, as detailed below.

Client

The tables below show the browsers currently supported, their earliest dates and a range of versions.

Desktop

Browser Name Earliest Versions
Chrome 2018-03 65-81, 83-123
Edge 2020-01 79-81, 83-121
Firefox 2018-05 60-124
Opera 2018-03 52-58, 60, 62-106
Safari 2018-09 12, 12.1, 13, 13.1, 14, 14.1, 15, 15.1,
15.2-15.6, 16.0-16.6, 17.0-17.4

Mobile

Browser Name Earliest Versions
Chrome for Android 121
Firefox for Android 122
Android Browser 121
Baidu Browser 13.18
Safari on iOS 2018-09 12.0-12.5, 13.0-13.7, 14.0-14.8,
15.0-15.8, 16.0-16.7, 17.0-17.3
KaiOS Browser 2021-09 3.0-3.1
Opera Mobile 73
Samsung Internet 2019-04 9.2, 10.1, 11.1-11.2, 12.0, 13.0, 14.0,
15.0, 16.0, 17.0, 18.0, 19.0, 20-23

Note: Safari is very sensitive to using LedgerSMB over HTTPS; using it with a regular HTTP connection is unsupported by the project team. Please be aware that using HTTPS is the recommended setup, so that Safari is considered to be fully supported.

Note: Earliest dates and versions come from http://caniuse.com. Only the most recent data is available for Mobile browsers other than Safari, because they are pushed out to the devices as soon as they are releases, so the number of devices running old browsers is negligible.

Quick start

For from-tarball installation instructions, see https://ledgersmb.org/content/installing-ledgersmb-111

Installation

This instruction assumes you have Docker installed as well as docker-compose.

 $ wget https://raw.githubusercontent.com/ledgersmb/ledgersmb-docker/1.11/docker-compose.yml
 $ docker-compose up -d

This creates both the LedgerSMB image and a database image with a persistent database. Note that this setup is not sufficient for production purposes because it lacks secure connections to protect your users' passwords.

Next steps

The system is installed and should be available for evaluation through

  • http://localhost:5762/setup.pl
    Creation and privileged management of company databases
  • http://localhost:5762/login.pl
    Normal login for the application

The system is ready for preparation for first use.

NOTE: This setup does not use a webserver like nginx or Apache. Setups which do include one will yield a faster user experience due to (much) faster page load times and web request responses. For production setups, please consider adding a webserver to the installation.

Project information

Security vulnerability reports: https://ledgersmb.org/contact/security_report

Web site: https://ledgersmb.org/

Repository: https://github.com/ledgersmb/LedgerSMB

Live chat: #ledgersmb:matrix.org (Matrix)

Groups:

Mailing lists:

Mailing list archives: https://archive.ledgersmb.org

Translations: Transifex online translation tool

Documentation: The book Running your business with LedgerSMB

Continuous integration (automated testing):

Code coverage: Coveralls

Project contributors

Source code contributors can be found in the project's Git commit history as well as in the CONTRIBUTORS file in the repository root.

Translation contributions can be found in the project's Git commit history as well as in the Transifex project Timeline.

Copyright

Copyright (c) 2006 - 2024 The LedgerSMB Project contributors
Copyright (c) 1999 - 2006 DWS Systems Inc (under the name SQL Ledger)

License

GPLv2

ledgersmb's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ledgersmb's Issues

Local change in LedgerSMB/Scripts/Payment.pm

John has the following "patch" is his local tree; we should investigate if we need to incorporate in the base line:

the other [patch] is in LedgerSMB/Scripts/Payment.pm
freelock: sub print
3 lines that change variable expansion, changing _$inv_id to _${inv_id}
must be something I fixed related to invoice numbers showing up on cash ->vouchers -> payments

Payment.sql::payment_post_bulk() doesn't handle foreign currencies correctly

Checking payment_post_bulk(sql/modules/Payment.sql#L486), I'm sure the payment processing is incorrect for FX situations:

As this is an accounting bug, it's my opinion we should be fixing this (and adding tests) with the highest possible urgency. It also warrents a quick 1.4.15 release once fixed.

However, since we didn't have anybody report problems, I think it's best to provide people with a diagnosis query/tool (maybe something in setup.pl) than that we immediately need to hurry to provide a fix query (unless it's easy to develop, of course).

Clarification of set functions versus record functions

There are loads of inconsistencies in our code base regarding returning a set of a single record versus returning just a record. E.g.

CREATE OR REPLACE FUNCTION account_heading_get (in_id int) RETURNS chart

versus

CREATE OR REPLACE FUNCTION account_get (in_id int) RETURNS setof chart

Possible patch required for IR.pm

John writes in IRC that he has this patch applied to IR.pm in his local install.

line 1456, changed to:

  •            WHERE eca.id = ? and coalesce(e2l.location_class, el.location_class) = 1|;
    

Impact to be investigated.

Can't post GL transaction

Due to Dojo's "required" checks, the additional (unused) rows in the GL entry screen report being "required". By consequence the form isn't being submitted.

Solution: as soon as either a debit or credit is entered, the account entry box should be set to "required" (but it should not be required until that time).

rewrite of currency and exchangerates

After the accounts, plan on refactoring currency and exchangerate handling. The plan is to have a buy/sell system which can be better constrained than what we have now and useful for individual transactions as we move into the financial rewrite.

The initial phase would be backwards-compatible largely with previous implementations.

New tables:

  • currency
    • symbol
    • allowed_variance
    • default

Would have a dojo form for adding currencies in a tabular manner, orderd by symbol

Eschangerate would have an fkey on symbol.

New urls:

.../currency/$symbol/ get: report of currency
.../currency/$symbol/ put/post, update currency
..,/currency/$symbol.json/xml get pr put currency
.../currency/$symbol/$bysell/$date get|post|put a new exchangerate (html/http form)
.../currency/$symbol/$bysell/$date.json|xml get|post|put

Fix invoice layout

Full dojo-ification of the UI created a regression where all fields in the invoice are now 15 ems wide. This means the invoice is much wider than it used to be and much wider than any reasonable browser window.

HTML 'required' attribute not validated by browsers for Dojo-non-form-elements

Input isn't fully validated by browsers if the 'required' attribute is available and if non-native-html form elements are in the forms (e.g. SELECT).

Solution is to create a form class which validates before it submits: lsmb/lib/Form; this class should derive from dojo/form/Form and should run "this.validate(); return !this.isValid();" in its onSubmit.

Test loading of preconfigured 'CoA' files

As part of our database testing routines, a test should be introduced to check that all provided CoA files can be succesfully loaded into LedgerSMB.

Point in case: we shipped spanish CoA files for many releases which couldn't be loaded at all.

Confusing situation regarding users, employees, admins

Currently the concepts of "users", "employees", "admins" and "login accounts/authentication entities" are conflated. This results in the following problems:

  • Multiple "User" objects:
    • DBObject::User
    • Entity::User
  • Multiple "save_roles" methods:
    • DBObject::Admin::save_roles()
    • Entity::User::save_roles()
  • Users are keyed off of different sequences
    • DBObject::User uses 'users.id' column
    • Entity::User uses 'entity.id' and/or 'users.entity_id' columns

In addition, the current design hard-wires logins (=users) to employees (=persons). Which means it becomes unnatural to create per-department accounts or even accounts for automated interfacing.

Adding new time card ends up in database error

I migrated 1.3 to 1.4.10.1 and I am seeing this

Error!

Internal Database Error
More information has been reported in the error logs at LedgerSMB.pm line 776.

dbversion: 1.4.10, company: foo

When Timecards -> Add Timecard -> Project

I have added Projects using 1.3 as well as 1.4, it fails consistently

Reporting units -> Projects -> Add unit

Clarification of various trial balance parts

Notably, there are 3 trial balance stored processes, of which only one seems to be used:

  • trial_balance__generate (used)
  • trial_balance_get (unused?)
  • report__trial_balance (unused?)

To support trial_balance_get, there are a number of (seemingly unused) trial balance tables:

  • trial_balance
  • trial_balance__account_to_report
  • trial_balance__heading_to_report

The last table (trial_balance__yearend_types) seems to be used in a dropdown on PNL and Balancesheet filters.

"Manage users" permission (at db creation) doesn't work

As of the consolidation of employee entry with contact management (or before?), the "manage users" permission for the initial user doesn't work anymore: the menu of a user created with those permissions consists only of:

  • Contacts -> Search
  • System -> Sessions
  • Preferences
  • New window
  • Logout

Note that there's no option to create users...

Tests for PR #767

In PR #767 I fixed two joins. Apparently, we don't have tests for the sprocs I fixed; this issue exists to correct that situation.

long-run: dojo/service oriented UI

Long run we want to move to a Dojo UI with a service oriented (JSON-based) back-end behind it.

How much we want to want to put in an HTML form vs a dojo widget may depend on the screen. My thinking is that long-run we may want a lot in dojo widgets because we may have a lot of multi-paned interfaces.

PGObject error when saving account or account heading

With master@e874c7874b220d64318534bd9ab8984103efdcb2, I'm getting the erro below, which blocks my testing of PR #793

Internal Database Error. Can't call method "can" on an undefined value at /usr/local/share/perl/5.14.2/PGObject.pm line 360
eval {...} called at /usr/local/share/perl/5.14.2/PGObject.pm line 360
PGObject::call_procedure('PGObject', 'funcname', 'account__save', 'registry', undef, 'dbh', 'DBI::db=HASH(0xb9947ac)', 'args', 'ARRAY(0xb998e70)', ...) called at /usr/local/share/perl/5.14.2/PGObject/Simple.pm line 237
PGObject::Simple::call_procedure('LedgerSMB::DBObject::Account=HASH(0xb995de4)', 'funcname', 'account__save', 'args', 'ARRAY(0xb998e70)', 'dbh', 'DBI::db=HASH(0xb9947ac)', 'funcprefix', '', ...) called at /usr/local/share/perl/5.14.2/PGObject/Simple.pm line 207
PGObject::Simple::call_dbmethod('LedgerSMB::DBObject::Account=HASH(0xb995de4)', 'funcname', 'account__save') called at LedgerSMB/DBObject/Account.pm line 88
LedgerSMB::DBObject::Account::save('LedgerSMB::DBObject::Account=HASH(0xb995de4)') called at LedgerSMB/Scripts/account.pm line 101
LedgerSMB::Scripts::account::save('LedgerSMB=HASH(0xb8f2a14)') called at lsmb-request.pl line 102
LedgerSMB::PSGI::try {...} () called at /usr/local/share/perl/5.14.2/Try/Tiny.pm line 81

Unable to run some links through a reverse-proxied setup

There are a few places in our code base where it's impossible to run LedgerSMB behind a reverse proxy. Trying to enumerate the spots in this ticket:

In UI/Reports/display_report.html, there is this html tag:

<form data-dojo-type="lsmb/lib/Form" method="post" action="<?lsmb ENVARS.SCRIPT_NAME ?>">

where ENVARS.SCRIPT_NAME contains full URI path of the script on the reverse-proxied URL, which doesn't match, if the reverse proxy runs on a different path.

In the same file (as well as PNL.html and balance_sheet.html), there's this snippet:

FORMATS = LIST_FORMATS();

PROTO='http';

IF (ENVARS.SERVER_PORT == '443') or 
   (ENVARS.HTTPS and ENVARS.HTTPS != 'OFF'); 
   PROTO='https'; 
END;

SERVER = ENVARS.SERVER_NAME;

IF (ENVARS.SERVER_PORT != '80') and ENVARS.SERVER_PORT
                                and (ENVARS.SERVER_PORT != '443');
   SERVER = SERVER _ ':' _ ENVARS.SERVER_PORT;
END;

QSTR=ENVARS.QUERY_STRING;

LINK = PROTO _ '://' _ SERVER _ ENVARS.SCRIPT_NAME 
           _ '?' _ QSTR _ '&company=' _ DBNAME;

LINK = LINK.replace('\&\&', '&');

Which constructs an absolute URL, leading to the same problems.

Financial rewrite: Journal and Ledger Design

Planning the following regarding the journal design and rewrite:

Database tables:

  • journal (stores journal identifiers, not journal entries, i.e, general journal, sales journal etc).
  • journal_entry (stores journal entry data)
  • journal_line (stores journal entry line items)

URL namespaces:

  • .../journal/general/entry/new/ (get a form for a new entry)
  • .../journal/general/entry/:id (show an entry by id, as a report)
  • .../journal/general/entry/:id.{html/json/xml/csv/pdf} (show entry with format shown)
  • .../ledger/general/:accno[.ext]?date_from=...&date_to=... General ledger for account
  • .../journal/search/... (current gl/search report)

Can't create a "root" heading

Highly impractical: It's currently impossible to create a heading which doesn't have a heading of its own -- a "root" heading. Due to this bug, it's not possible to execute all restructuring actions a user might need/want to execute.

remove frames from master

The approach will be to wrap the current forms in Dojo forms, and then basically intercepting the submit request, make it as an xhr request, and the nrewrite the form div with the response.

Phase out 'chart' view

The 'chart' view is a mix of accounts and headings, which is a union of the account and account_heading tables -- it used to be a table of its own though.

The separation in accounts and headings has been created explicitly to support code to use e.g. account heading trees. The 'chart' view, being legacy, should be phased out.

Employee creation workflow not sufficiently intuitive

The workflow to create an employee starts out with the general "contact" screen (company/person). Then, after saving the person, a completely different screen appears which is called the employee entry screen. Fields entered in the previous screen (such as Tax/SSN) are cleared in the new screen and need to be re-entered again.

IMO, this screen should be presented right away, regardless of how things work under the hood.

Journal entry drops 10th account

When clicking "Update" on the Journal entry screen with 10 filled lines, the returned screen contains the figures entered on the 10th line, but not the account.

design chart of accounts account entry/edit interface

The reason for this is that we cannot support cash flow statements without some additional categorization of accounts. To do this, I expect to add a subclassification for cash flow statement section.

Additionally, this is one of our composite interfaces, and therefore this seems to be a good time to bring it to dancer, add appropriate web services, etc. Currency and Exchangerate handling will follow shortly afterwards.

I would also like to conbsider generalizing headings off to allow heading classification (a system similar to reporting units) but this may not happen with this revision. The idea is that way an account could be attached to several different heading trees (one for managmenet accounting, one for financial accounting etc).

URL proposals (... referring to the lsmb root url):

  - .../accounts/ coa (get)
  - .../accounts.(html|json|xml|csv) (get/post)
  - .../accounts/:accno.(html|json|xml) (get/put)

The current dropdowns that use accounts would have to be moved to thie above url system

users and users_preference tables design cleanup

The users table maps user names to user IDs (and to entities). The user_preference table lists the user's preferences based on the user's ID. The problem is that it does so by listing all preferences on a single row. This way, the users and user_prefence tables can be merged; another option (much more flexible) would be to list each preference on a separate row in the user_preference table.

Sales/Purchase Journal (Rewrite with financial rewrite)

This will not occur before the gl rewrite. New tables will include eca_journal_entry which will connect entity_credit_account to journal_entry

New procedures will include:

  • eca_journal_entry__get(id int) which will get the appicable sales/purchase entry)
  • eca_je_save(self eca_je) will save the eca journal entry (eca_je is the new type)

URLs:

  • .../journal/(sales|purchase)/new get|put|post, getting the new form or posting/putting it.
  • .../journal(sales|purchase)/id.fmt (fmt being html, xml, or csv), get to retrieve, post to approbve
  • .../journal/(sales|purchase)/(search|outstanding|aging) for relevant reports, get only

Year-closing complains about unapproved transactions, but none visible in UI

Going through my database, I found why: There's a transaction which has status "approved" 'f':

select * from ap where transdate <= '2015-12-31'::date and not approved;

Returns:

 id  | invnumber | transdate  | entity_id | taxincluded | amount | netamount | paid | datepaid |  duedate   | invoice | ordnumber | curr | notes | person_id | till | quonumber | intnotes | department_id | shipvia | language_code | ponumber | shippingpoint | on_hold | approved | reverse | terms | description | force_closed | entity_credit_account |   crdate
-----+-----------+------------+-----------+-------------+--------+-----------+------+----------+------------+---------+-----------+------+-------+-----------+------+-----------+----------+---------------+---------+---------------+----------+---------------+---------+----------+---------+-------+-------------+--------------+-----------------------+------------
  66 | 6         | 2013-08-28 |           | f           |  83.57 |     69.07 | 0.00 |          | 2013-08-28 | f       |           | EUR  |       |         1 |      |           |          |             0 |         |               |          |               | f       | f        | f       |     0 |             |              |                    14 | 2013-08-28

Then, going to the vouchers table, it turns out the transaction is associated with a voucher:

select * from voucher where trans_id=66;

Returns:

 trans_id | batch_id | id | batch_class
----------+----------+----+-------------
       66 |       18 | 14 |           4

And then in the last step, it turns out that the batch is of class 4 as suggested by the previous result, and the batch is approved too:

select * from batch where id = 18;

returns:

 id | batch_class_id | control_code | description | default_date | approved_on | approved_by | created_by | locked_by | created_on
----+----------------+--------------+-------------+--------------+-------------+-------------+------------+-----------+------------
 18 |              4 | B-11150      | B-11150     | 2013-08-28   | 2013-10-06  |           1 |          1 |       380 | 2013-10-06

However, looking at the function batch_post(), the function doesn't update the AR/AP/GL tables for this type of batch.

How this transaction got into this type of batch, I have no idea.

Interaction between defaults and user_preference tables

It would seem that preferences should cascade from the user level to the global configured defaults, to fall back to the built in defaults only as a last step.

Currently, the user_preference and defaults tables are independent entirely.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.