ProfessionalAccounting icon indicating copy to clipboard operation
ProfessionalAccounting copied to clipboard

Accounting software with debit and credit. 使用借贷记帐法的记账软件

ProfessionalAccounting

使用借贷记帐法的记账软件 Accounting software with debit and credit

Appveyor Build Appveyor Tests Coveralls

简介 Introduction

  • Double-entry bookkeeping
  • Client/Server architecture
  • DSL (Domain Specfic Langauge) for CRUD
  • Backend
    • Monolithic architecture, business logic C# 10.0编写
    • Uses MongoDB as the database
    • Compiled on the .NET 8.0 platform
    • Uses nginx as a reverse proxy, supports TLSv1.3、HTTP/3
    • Deployed using Docker
  • Frontend
    • Uses Redux for state management
    • Uses p5.js for UI rendering
    • Uses webpack for bundling

功能 Functionalities

  • Fast entry of common vouchers 常见记账凭证的快速录入
  • Fast entry of split bill expenses AA制消费的快速录入
  • Multi-currency accounting, even within a single voucher 多币种记账(支持一张记账凭证多个币种共存)
  • Exchange rate inquiry / conversion 汇率查询与自动转换(在分类汇总时可按本位币显示外币)
  • Multi-users, transferring money to each other 多用户互相转账(支持一张记账凭证多个用户共存)
  • Mutable accounting base currency 记账本位币变动(所有者权益币种变动)
  • Fixed asset management 固定资产管理(购置登记、折旧、贬值与处置)
  • Automatic amortization 自动摊销
  • Monthly / annually revenue carrying 期末结转
  • JSON/CSV import / export 导入/导出
  • Joint property and cash flow for spouses / partners (妻妻)共同财产现金流分析
  • Cheque management 支票管理
  • Interest calulation of debt 利息收入与费用计算
  • Investment return calculation 投资收益率计算
  • Interest calculation of deposit 活期存款利息计算
  • Cash flow forecasting 现金流预估
  • Entry of foreign currency transactions on credit cards 信用卡外币交易入账
  • Credit card statement reconciliation 信用卡对账
  • Spreadsheet reconciliation & statistics 表格对账统计

安装与配置

本项目提供两种部署方式:

  1. 本地/内网调试(无TLS,无客户端认证,无可靠数据存储)
  2. 网络部署(TLS,客户端证书,MongoDB Atlas数据库后端)

准备

首先准备一台Linux服务器,安装以下软件:

  • docker,推荐采用get.docker.com
  • (仅限网络部署)openssl(请自行检索安装方法)

配置记账系统功能

为了方便地从GitHub下载单独文件(而不用下载整个repo的整个历史), 此处推荐大家使用git-get来下载。

  1. ssh登录服务器
  2. 下载docker-compose.yml文件(网络部署)或者docker-compose.local.yml(本地部署):
    git get b1f6c1c4/ProfessionalAccounting -- docker-compose.yml
    git get b1f6c1c4/ProfessionalAccounting -- docker-compose.local.yml
    
  3. 下载示例配置文件夹,放在/data/accounting/config.d/(网络部署):
    mkdir -p /data/accounting
    git get -o /data/accounting/config.d b1f6c1c4/ProfessionalAccounting -- example/config.d/
    
  4. 修改必须修改的配置文件:
    • BaseCurrency.xml - 记账本位币
    • Symbol.xml - 货币符号表
    • Titles.xml - 记账科目列表
    • Carry.xml - 期末结转规则
    • Exchange.xml - 汇率查询API(fixer.ioCoinMarketCap)的配置
  5. 修改可选的配置文件:
    • Abbr.xml - 登记新记账凭证时使用的缩写列表
    • Cash.xml - 现金流插件相关配置
    • Composite.xml - 常用检索式列表
    • Util.xml - 快速登记记账凭证插件的配置
    • SpreadSheet.xml - 表格形式对账插件的配置

配置服务器和客户端x509证书(仅限网络部署)

  1. 将服务器证书和私钥(server.crtserver.key)放在服务器的/data/accounting/certs目录下
    1. 如果你没有服务器证书,推荐使用 acme.sh 来免费获得一个
  2. 在服务器上创建dhparams:
    openssl dhparam -out /data/accounting/certs/dhparam.pem 2048
    
  3. 创建自签名的客户端证书和私钥: (注意:如果客户端机器未安装openssl,则在服务器上创建客户端的证书和私钥,并把加密后的私钥client.p12传回客户端)
    1. 在客户端机器上创建证书和私钥:
    openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.crt -days 1825 -nodes
    chmod 0400 key.pem
    
    1. 将证书上传服务器:
    scp ./cert.crt <server>:/data/accounting/certs/client.crt
    
    1. 将证书和私钥封装成.p12格式,删除原来的.pem文件: (这一步的目的是方便在客户端上安装证书)
    openssl pkcs12 -export -inkey key.pem -in cert.crt -out client.p12 && rm -f key.pem
    
  4. 在客户端上安装证书:
    1. 恕不赘述,请自行Google install p12 certificate on XXXXXX=Linux/FreeBSD/Windows/MacOS/iOS/iPadOS/...)

启动、停止

直接使用docker-compose启动,将在18080端口侦听请求:

  • 本地部署:
    docker compose -f docker-compose.local.yml up -d   # start
    docker compose down     # stop
    
  • 网络部署:
    docker compose up -d    # start
    docker compose down     # stop
    

基本使用方法

记账(记账凭证的增加、修改与删除)

记账过程

  1. 在客户端上使用浏览器访问服务器的18080端口:http://<server>:18080/(本地)或https://<server>:18080/(网络)
  2. 可以看到用户界面分为两部分:上面的一行命令框和下面的编辑器
  3. 在命令框中,输入命令:login <username>并按回车
    • <username>是你在记账系统中的用户名
    • 无需注册,没有密码,用户名只是个代号而已
    • 用户名会在前端存储在localstorage中,无需每次login
  4. 按tab可以在命令框和编辑器之间切换
  5. 执行空白命令会在编辑器中添加一个空的记账凭证模板(@new Voucher { }@
  6. 在模板中需要填写记账凭证的内容,也就是用什么货币关于什么、交易了多少钱
    • 例子:T1001 -5
      • 字面意思是:我(刚刚login的用户名)、用本位币(参考BaseCurrency.xml)、关于库存现金(参考Titles.xml)、交易了-5元
      • 翻译过来就是:现金少了5元人民币(假设你没有修改BaseCurrency.xml
    • 例子:sp 5
      • 字面意思是:我、用本位币、关于食品(参考Abbr.xml)、交易了5元
      • 翻译过来就是:食品开销增加了5元人民币
    • 两个例子合在一起,就表明了“今天我用5元人民币现金购买了5元的食品”
  7. 按Alt+Enter保存记账凭证,可以看到增加了不少信息:
    • ^5edc...^ 这是mongoDB的_id,用于唯一标识记账凭证
    • 20200606 这是交易发生的日期,在保存记账凭证的时刻被记录下来了
    • // 库存现金 这是注释,以免使用者忘记记账科目
    • T1001 -5 与保存之前的写法和语义完全相同
    • T660206 '食品' 5 这是从sp 5翻译过来的完整写法
      • Abbr.xml里面已经规定了sp就是T660206 '食品'的简称,所以在保存记账凭证时变回原样也不足为奇
  8. 按Alt+Delete可以删除已经保存的记账凭证
    • 如果记账凭证尚且没有保存,那么它也就无所谓删除,一旦刷新页面就会丢掉
  9. 对于已经保存了的记账凭证,再次按Alt+Enter可以修改它的内容

注意:记账凭证不能嵌套,如果不小心在一个记账凭证模板里面又嵌套了一个模板,请立即按Ctrl+Z撤销。

检索

检索过程

在命令框中执行检索命令可以列出相应的记账凭证:

注意:执行命令会覆盖下方编辑器中的全部内容;如果你希望在编辑器中添加而非覆盖,请在命令框中按Shift+Enter。

  • . - 今天都发生了什么交易
  • .. - 昨天都发生了什么交易
  • T1001 . - 今天都发生了什么现金交易
  • T660206 食品 0 - 这个月都发生了什么食品交易
    • 注意这里不能使用sp缩写
  • unsafe 2020 - 在2020年都发生了什么交易
    • 由于可能返回非常多的结果,这里需要加上关键词unsafe
  • 关于记账凭证检索式(DSL)的具体语法,可以在命令框中输入?命令调出帮助文档

汇总

汇总过程

在命令框中执行分类汇总命令可以对帐务数据进行统计:

  • ` - 我的基本财务报表
  • 0 ` - 我这个月的资金变动情况
  • ~-1 ` - 我上个月的基本财务报表
  • 关于分类汇总检索式(DSL)的具体语法,可以在命令框中输入?命令调出帮助文档

开发

项目文件结构

  • nginx - 前端
  • AccountingServer - HTTP Server
  • AccountingServer.Shell - 记账凭证的序列化/反序列化,分类汇总的显示
  • AccountingServer.BLL - 汇率转换,分类汇总,固定资产处理,摊销处理
  • AccountingServer.DAL - mongoDB数据库访问
  • AccountingServer.Entities - 基本对象结构定义
  • AccountingServer.QueryGeneration - 基于Antlr4的DSL Parser
  • AccountingServer.Test - 单元测试和集成测试

本地后端开发环境

在Linux上构建开发环境

  1. 请先安装以下工具:

  2. 启动测试数据库:

    docker run -d --rm --name mongo -p 27017:27017 mongo
    
  3. 启动Rider即可。

在Windows上构建开发环境

  1. 请先安装以下工具:
  2. 启动测试数据库:在services.msc中启动MongoDB服务。
  3. 启动Visual Studio即可。

本地前端开发环境

  1. 请先安装以下工具:

  2. 下载所需npm包:

    cd nginx && npm install
    
  3. 启动webpack开发环境:

    npm run serve
    

许可

本项目以GNU AGPL v3.0协议开源。 This project is licensed under GNU AGPL v3.0 only. (AGPL-3.0-only).

注解:(请参阅协议原文,以下解释没有法律效力)

  • 若个人开发者采用客户端证书的方式将端口保护起来,阻止自己以外的其他任何人访问, 这种行为不算“making available to the public”,也不构成协议中的 “propagate/convey/remote network interaction”, 因此将不受GNU AGPL v3.0协议的限制
  • 但是若个人开发者不采用任何方式保护端口,其他人将有可能通过网络与该软件交互 (“remote network interaction”),这种行为就算作“convey”了。 这种情况下该行为受到GNU AGPL v3.0协议的限制,必须提供与后端程序的版本一致完整的源代码。