zjz-cli 0.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- zjz_cli-0.0.1/PKG-INFO +65 -0
- zjz_cli-0.0.1/README.md +42 -0
- zjz_cli-0.0.1/app/__init__.py +0 -0
- zjz_cli-0.0.1/app/api/__init__.py +0 -0
- zjz_cli-0.0.1/app/api/zjz_api.py +184 -0
- zjz_cli-0.0.1/app/api/zjz_req.py +22 -0
- zjz_cli-0.0.1/app/module/__init__.py +0 -0
- zjz_cli-0.0.1/app/module/account.py +47 -0
- zjz_cli-0.0.1/app/module/bank.py +49 -0
- zjz_cli-0.0.1/app/module/employee.py +48 -0
- zjz_cli-0.0.1/app/module/invoice.py +96 -0
- zjz_cli-0.0.1/app/module/payroll.py +79 -0
- zjz_cli-0.0.1/app/module/todo.py +45 -0
- zjz_cli-0.0.1/app/service/__init__.py +0 -0
- zjz_cli-0.0.1/app/service/account_service.py +103 -0
- zjz_cli-0.0.1/app/service/bank_service.py +122 -0
- zjz_cli-0.0.1/app/service/config_manager.py +92 -0
- zjz_cli-0.0.1/app/service/employee_service.py +63 -0
- zjz_cli-0.0.1/app/service/invoice_service.py +231 -0
- zjz_cli-0.0.1/app/service/payroll_service.py +56 -0
- zjz_cli-0.0.1/app/service/todo_service.py +81 -0
- zjz_cli-0.0.1/app/util/__init__.py +0 -0
- zjz_cli-0.0.1/app/util/echo_util.py +9 -0
- zjz_cli-0.0.1/app/util/http_client.py +80 -0
- zjz_cli-0.0.1/main.py +24 -0
- zjz_cli-0.0.1/pyproject.toml +40 -0
- zjz_cli-0.0.1/setup.cfg +4 -0
- zjz_cli-0.0.1/zjz_cli.egg-info/PKG-INFO +65 -0
- zjz_cli-0.0.1/zjz_cli.egg-info/SOURCES.txt +31 -0
- zjz_cli-0.0.1/zjz_cli.egg-info/dependency_links.txt +1 -0
- zjz_cli-0.0.1/zjz_cli.egg-info/entry_points.txt +2 -0
- zjz_cli-0.0.1/zjz_cli.egg-info/requires.txt +16 -0
- zjz_cli-0.0.1/zjz_cli.egg-info/top_level.txt +2 -0
zjz_cli-0.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: zjz_cli
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: 自记账的工具箱
|
|
5
|
+
Requires-Python: >=3.8
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
Requires-Dist: annotated-doc>=0.0.4
|
|
8
|
+
Requires-Dist: anyio>=4.0.0
|
|
9
|
+
Requires-Dist: certifi>=2024.2.25
|
|
10
|
+
Requires-Dist: click>=8.3.1
|
|
11
|
+
Requires-Dist: h11>=0.16.0
|
|
12
|
+
Requires-Dist: httpcore>=1.0.9
|
|
13
|
+
Requires-Dist: httpx>=0.28.1
|
|
14
|
+
Requires-Dist: idna>=3.0
|
|
15
|
+
Requires-Dist: markdown-it-py>=4.0.0
|
|
16
|
+
Requires-Dist: mdurl>=0.1.2
|
|
17
|
+
Requires-Dist: packaging>=24.0
|
|
18
|
+
Requires-Dist: Pygments>=2.10.0
|
|
19
|
+
Requires-Dist: rich>=14.3.3
|
|
20
|
+
Requires-Dist: shellingham>=1.5.4
|
|
21
|
+
Requires-Dist: typer>=0.24.1
|
|
22
|
+
Requires-Dist: typing_extensions>=4.12.0
|
|
23
|
+
|
|
24
|
+
## zjz_cli
|
|
25
|
+
|
|
26
|
+
Cli tool for zjz
|
|
27
|
+
|
|
28
|
+
### Use VENV
|
|
29
|
+
|
|
30
|
+
```shell
|
|
31
|
+
mkdir .venv
|
|
32
|
+
cd .venv
|
|
33
|
+
python3.12 -m venv .
|
|
34
|
+
source .venv/bin/activate
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Install dependence
|
|
38
|
+
|
|
39
|
+
```shell
|
|
40
|
+
pip install -r requirements.txt
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Build
|
|
44
|
+
|
|
45
|
+
```shell
|
|
46
|
+
pyinstaller --onefile --name zjz_cli --clean --noupx main.py
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Dependence
|
|
50
|
+
|
|
51
|
+
If you add dependence, add here
|
|
52
|
+
|
|
53
|
+
```shell
|
|
54
|
+
pip install typer
|
|
55
|
+
pip install pyinstaller
|
|
56
|
+
pip install httpx
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Export requirements
|
|
60
|
+
|
|
61
|
+
If you add dependence, export it
|
|
62
|
+
|
|
63
|
+
```shell
|
|
64
|
+
pip freeze > requirements.txt
|
|
65
|
+
```
|
zjz_cli-0.0.1/README.md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
## zjz_cli
|
|
2
|
+
|
|
3
|
+
Cli tool for zjz
|
|
4
|
+
|
|
5
|
+
### Use VENV
|
|
6
|
+
|
|
7
|
+
```shell
|
|
8
|
+
mkdir .venv
|
|
9
|
+
cd .venv
|
|
10
|
+
python3.12 -m venv .
|
|
11
|
+
source .venv/bin/activate
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
### Install dependence
|
|
15
|
+
|
|
16
|
+
```shell
|
|
17
|
+
pip install -r requirements.txt
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### Build
|
|
21
|
+
|
|
22
|
+
```shell
|
|
23
|
+
pyinstaller --onefile --name zjz_cli --clean --noupx main.py
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Dependence
|
|
27
|
+
|
|
28
|
+
If you add dependence, add here
|
|
29
|
+
|
|
30
|
+
```shell
|
|
31
|
+
pip install typer
|
|
32
|
+
pip install pyinstaller
|
|
33
|
+
pip install httpx
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Export requirements
|
|
37
|
+
|
|
38
|
+
If you add dependence, export it
|
|
39
|
+
|
|
40
|
+
```shell
|
|
41
|
+
pip freeze > requirements.txt
|
|
42
|
+
```
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
from app.api.zjz_req import zjz_req
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def sms_verify_code(phone: str) -> dict:
|
|
5
|
+
return zjz_req.get_client().post_json('login/sms', {
|
|
6
|
+
'phone': phone,
|
|
7
|
+
})
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def verify_sms_code(phone: str, code: str) -> dict:
|
|
11
|
+
return zjz_req.get_client().post_json('login/sms-2-token', {
|
|
12
|
+
'phone': phone,
|
|
13
|
+
'sms': code,
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def get_employee_list(uid: str = None, keyword: str = '', page: int = 1) -> dict:
|
|
18
|
+
if not page or page < 1:
|
|
19
|
+
page = 1
|
|
20
|
+
return zjz_req.get_client().get('ryxx', params={
|
|
21
|
+
'uid': uid,
|
|
22
|
+
'keyword': keyword,
|
|
23
|
+
'page': page
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def add_employee(uid: str, data: dict) -> dict:
|
|
28
|
+
data['uid'] = uid
|
|
29
|
+
return zjz_req.get_client().post_json('ryxx', data)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def update_employee(employee_id: str, data: dict) -> dict:
|
|
33
|
+
return zjz_req.get_client().put('ryxx', {
|
|
34
|
+
'id': employee_id,
|
|
35
|
+
'data': data,
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def get_payroll(uid: str, year: int, month: int) -> dict:
|
|
40
|
+
month_str = f"{year}-{month:02d}"
|
|
41
|
+
return zjz_req.get_client().get('payroll', params={
|
|
42
|
+
'uid': uid,
|
|
43
|
+
'month': month_str
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def get_payroll_creation_status(uid: str, year: int, month: int) -> dict:
|
|
48
|
+
month_str = f"{year}-{month:02d}"
|
|
49
|
+
return zjz_req.get_client().get('payroll/creation-status', params={
|
|
50
|
+
'uid': uid,
|
|
51
|
+
'month': month_str
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def get_preview_payroll(uid: str, year: int, month: int) -> dict:
|
|
56
|
+
month_str = f"{year}-{month:02d}"
|
|
57
|
+
return zjz_req.get_client().get('payroll/preview', params={
|
|
58
|
+
'uid': uid,
|
|
59
|
+
'month': month_str
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def create_payroll(uid: str, year: int, month: int, data: list) -> dict:
|
|
64
|
+
month_str = f"{year}-{month:02d}"
|
|
65
|
+
return zjz_req.get_client().post_json('payroll', {
|
|
66
|
+
'uid': uid,
|
|
67
|
+
'month': month_str,
|
|
68
|
+
'data': data
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def get_sales_invoice_data_list(uid: str, current: int = 1, invoice_number: str = '', invoice_date_begin: str = '', invoice_date_end: str = '', status: str = '') -> dict:
|
|
73
|
+
return zjz_req.get_client().get('invoice/sales_invoice_data_list', params={
|
|
74
|
+
'uid': uid,
|
|
75
|
+
'current': current,
|
|
76
|
+
'invoice_number': invoice_number,
|
|
77
|
+
'invoice_date_begin': invoice_date_begin,
|
|
78
|
+
'invoice_date_end': invoice_date_end,
|
|
79
|
+
'status': status,
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def set_month_no_sales_invoice(uid: str, year: int, month: int) -> dict:
|
|
84
|
+
return zjz_req.get_client().post_json('invoice/set_month_no_sales_invoice', {
|
|
85
|
+
'uid': uid,
|
|
86
|
+
'year': year,
|
|
87
|
+
'month': month,
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def get_income_invoice_data_list(uid: str, current: int = 1, invoice_number: str = '', invoice_date_begin: str = '', invoice_date_end: str = '', status: str = '') -> dict:
|
|
92
|
+
return zjz_req.get_client().get('invoice/income_invoice_data_list', params={
|
|
93
|
+
'uid': uid,
|
|
94
|
+
'current': current,
|
|
95
|
+
'invoice_number': invoice_number,
|
|
96
|
+
'invoice_date_begin': invoice_date_begin,
|
|
97
|
+
'invoice_date_end': invoice_date_end,
|
|
98
|
+
'status': status,
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def set_month_no_invoice(uid: str, year: int, month: int) -> dict:
|
|
103
|
+
return zjz_req.get_client().post_json('invoice/set_month_no_invoice', {
|
|
104
|
+
'uid': uid,
|
|
105
|
+
'year': year,
|
|
106
|
+
'month': month,
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def invoice_can_choose_use_list(uid: str, goods_name: str, total_tax_price: str, total_money: str) -> dict:
|
|
111
|
+
return zjz_req.get_client().get('invoice/invoice_can_choose_use_list', params={
|
|
112
|
+
'uid': uid,
|
|
113
|
+
'goods_name': goods_name,
|
|
114
|
+
'total_tax_price': total_tax_price,
|
|
115
|
+
'total_money': total_money,
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def invoice_choose_use(uid: str, invoice_id: int, category: str, is_pay: str, payee: str) -> dict:
|
|
120
|
+
return zjz_req.get_client().post_json('invoice/invoice_choose_use', {
|
|
121
|
+
'uid': uid,
|
|
122
|
+
'invoice_id': invoice_id,
|
|
123
|
+
'category': category,
|
|
124
|
+
'is_pay': is_pay,
|
|
125
|
+
'payee': payee,
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def get_todo_list(uid: str = '') -> dict:
|
|
130
|
+
params = {}
|
|
131
|
+
if uid:
|
|
132
|
+
params['uid'] = uid
|
|
133
|
+
return zjz_req.get_client().get('todo-list', params=params)
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def before_set_month_audited(year: int, month: int, uid: str = '') -> dict:
|
|
137
|
+
params = {
|
|
138
|
+
'year': year,
|
|
139
|
+
'month': month,
|
|
140
|
+
}
|
|
141
|
+
if uid:
|
|
142
|
+
params['uid'] = uid
|
|
143
|
+
return zjz_req.get_client().get('audit/before_set_month_audited', params=params)
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def set_month_audited(year: int, month: int, uid: str = '') -> dict:
|
|
147
|
+
payload = {
|
|
148
|
+
'year': year,
|
|
149
|
+
'month': month,
|
|
150
|
+
}
|
|
151
|
+
if uid:
|
|
152
|
+
payload['uid'] = uid
|
|
153
|
+
return zjz_req.get_client().post_json('audit/set_month_audited', payload)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def get_bank_bill_data_list(uid: str, current: int = 1, date_begin: str = '', date_end: str = '') -> dict:
|
|
157
|
+
params = {
|
|
158
|
+
'current': current,
|
|
159
|
+
'date_begin': date_begin,
|
|
160
|
+
'date_end': date_end,
|
|
161
|
+
}
|
|
162
|
+
if uid:
|
|
163
|
+
params['uid'] = uid
|
|
164
|
+
return zjz_req.get_client().get('bank/bill_data_list', params=params)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def choose_bank_use(uid: str, bill_id: int, rule_text: str) -> dict:
|
|
168
|
+
payload = {
|
|
169
|
+
'id': bill_id,
|
|
170
|
+
'rule_text': rule_text,
|
|
171
|
+
}
|
|
172
|
+
if uid:
|
|
173
|
+
payload['uid'] = uid
|
|
174
|
+
return zjz_req.get_client().post_json('bank/bank_bill_choose_use', payload)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def set_month_bank_no_water(uid: str, year: int, month: int) -> dict:
|
|
178
|
+
payload = {
|
|
179
|
+
'year': year,
|
|
180
|
+
'month': month,
|
|
181
|
+
}
|
|
182
|
+
if uid:
|
|
183
|
+
payload['uid'] = uid
|
|
184
|
+
return zjz_req.get_client().post_json('bank/set_month_no_water', payload)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from app.service.config_manager import cfg_mgr
|
|
2
|
+
from app.util.http_client import HttpClient
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class ZjzReq:
|
|
6
|
+
def __init__(self):
|
|
7
|
+
self.headers = {}
|
|
8
|
+
self.base_url: str = "https://www.zijizhang.com/ai/skill"
|
|
9
|
+
self.client = None
|
|
10
|
+
|
|
11
|
+
def get_client(self):
|
|
12
|
+
auth_token = self.headers.get('Authorization')
|
|
13
|
+
if not auth_token:
|
|
14
|
+
token = cfg_mgr.get_config('token')
|
|
15
|
+
if token:
|
|
16
|
+
self.headers['Authorization'] = f'Bearer {token}'
|
|
17
|
+
self.client = None
|
|
18
|
+
if not self.client:
|
|
19
|
+
self.client = HttpClient(base_url=self.base_url, headers=self.headers)
|
|
20
|
+
return self.client
|
|
21
|
+
|
|
22
|
+
zjz_req = ZjzReq()
|
|
File without changes
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import typer
|
|
2
|
+
|
|
3
|
+
from app.service.account_service import AccountService
|
|
4
|
+
from app.util import echo_util
|
|
5
|
+
|
|
6
|
+
account_app = typer.Typer()
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@account_app.command(
|
|
10
|
+
name='get_sms_verify_code',
|
|
11
|
+
help='获取登录的短信验证码',
|
|
12
|
+
no_args_is_help=True)
|
|
13
|
+
def get_sms_verify_code(phone: str = typer.Argument(..., help='自记账的登录手机号')):
|
|
14
|
+
service = AccountService()
|
|
15
|
+
res = service.sms_verify_code(phone)
|
|
16
|
+
echo_util.echo_http_res(res)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@account_app.command(
|
|
20
|
+
name='verify_sms_code',
|
|
21
|
+
help='通过短信验证码登录',
|
|
22
|
+
no_args_is_help=True)
|
|
23
|
+
def verify_sms_code(
|
|
24
|
+
phone: str = typer.Argument(..., help='手机号'),
|
|
25
|
+
code: str = typer.Argument(..., help='短信验证码')):
|
|
26
|
+
service = AccountService()
|
|
27
|
+
res = service.sms_code_login(phone, code)
|
|
28
|
+
echo_util.echo_http_res(res)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@account_app.command(
|
|
32
|
+
name='get_switchable_users',
|
|
33
|
+
help='获取可切换的公司列表')
|
|
34
|
+
def get_switchable_users():
|
|
35
|
+
service = AccountService()
|
|
36
|
+
res = service.get_switchable_user()
|
|
37
|
+
echo_util.echo_http_res(res)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@account_app.command(
|
|
41
|
+
name='switch_to',
|
|
42
|
+
help='切换公司',
|
|
43
|
+
no_args_is_help=True)
|
|
44
|
+
def switch_to(uid: str = typer.Argument(..., help='公司唯一标识uid')):
|
|
45
|
+
service = AccountService()
|
|
46
|
+
res = service.switch_to(uid)
|
|
47
|
+
echo_util.echo_http_res(res)
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import typer
|
|
2
|
+
|
|
3
|
+
from app.service.bank_service import BankService
|
|
4
|
+
from app.util import echo_util
|
|
5
|
+
|
|
6
|
+
bank_app = typer.Typer()
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@bank_app.command(
|
|
10
|
+
name='get_bank_bill_data_list',
|
|
11
|
+
help="获取银行回单/流水列表")
|
|
12
|
+
def get_bank_bill_data_list(
|
|
13
|
+
uid: str = typer.Option('', '--uid', help='公司唯一标识uid(不传则使用当前已切换在用的 uid)'),
|
|
14
|
+
current: int = typer.Option(1, '--current', help='页码,默认 1'),
|
|
15
|
+
date_begin: str = typer.Option('', '--date_begin', help='交易日期开始(YYYY-MM-DD;如需使用需与 date_end 同时传)'),
|
|
16
|
+
date_end: str = typer.Option('', '--date_end', help='交易日期结束(YYYY-MM-DD;如需使用需与 date_begin 同时传)'),
|
|
17
|
+
):
|
|
18
|
+
service = BankService()
|
|
19
|
+
res = service.get_bank_bill_data_list(uid, current, date_begin, date_end)
|
|
20
|
+
echo_util.echo_http_res(res)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@bank_app.command(
|
|
24
|
+
name='choose_bank_use',
|
|
25
|
+
help="回单选择用途/入账",
|
|
26
|
+
no_args_is_help=True)
|
|
27
|
+
def choose_bank_use(
|
|
28
|
+
bill_id: int = typer.Argument(...,help='回单单据 id(来自 get_bank_bill_data_list 返回 bill_list[].id)'),
|
|
29
|
+
rule_text: str = typer.Argument(..., help='用途文本(建议从 bill_list[].use_list 中选择)'),
|
|
30
|
+
uid: str = typer.Option('', '--uid', help='公司唯一标识uid(不传则使用当前已切换在用的 uid)'),
|
|
31
|
+
):
|
|
32
|
+
service = BankService()
|
|
33
|
+
res = service.choose_bank_use(uid, bill_id, rule_text)
|
|
34
|
+
echo_util.echo_http_res(res)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@bank_app.command(
|
|
38
|
+
name='set_month_bank_no_water',
|
|
39
|
+
help="标记某个月份无银行回单/流水",
|
|
40
|
+
no_args_is_help=True)
|
|
41
|
+
def set_month_bank_no_water(
|
|
42
|
+
year: int = typer.Argument(..., help='年份,如 2026'),
|
|
43
|
+
month: int = typer.Argument(..., help='月份(1-12),如 3'),
|
|
44
|
+
uid: str = typer.Option('', '--uid', help='公司唯一标识uid(不传则使用当前已切换在用的 uid)'),
|
|
45
|
+
):
|
|
46
|
+
service = BankService()
|
|
47
|
+
res = service.set_month_bank_no_water(uid, year, month)
|
|
48
|
+
echo_util.echo_http_res(res)
|
|
49
|
+
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import typer
|
|
3
|
+
|
|
4
|
+
from app.service.employee_service import EmployeeService
|
|
5
|
+
from app.util import echo_util
|
|
6
|
+
|
|
7
|
+
employee_app = typer.Typer()
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@employee_app.command(
|
|
11
|
+
name='get_employee_list',
|
|
12
|
+
help="获取员工列表",
|
|
13
|
+
epilog="""使用示例\n\nzjz_cli employee get_employee_list""")
|
|
14
|
+
def get_employee_list(
|
|
15
|
+
uid: str = typer.Option('', '--uid', help='公司唯一标识uid'),
|
|
16
|
+
keyword: str = typer.Option('', '--keyword', help='姓名/证件号码 关键字,支持模糊搜索,如果为空则查询全部')
|
|
17
|
+
):
|
|
18
|
+
service = EmployeeService()
|
|
19
|
+
res = service.get_employee_list(uid, keyword)
|
|
20
|
+
echo_util.echo_http_res(res)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@employee_app.command(
|
|
24
|
+
name='add_employee',
|
|
25
|
+
help="添加员工",
|
|
26
|
+
no_args_is_help=True)
|
|
27
|
+
def add_employee(
|
|
28
|
+
data: str = typer.Argument(..., help='员工信息的json字符串'),
|
|
29
|
+
uid: str = typer.Option('', '--uid', help='公司唯一标识uid')
|
|
30
|
+
):
|
|
31
|
+
data_obj = json.loads(data)
|
|
32
|
+
service = EmployeeService()
|
|
33
|
+
res = service.add_employee(uid, data_obj)
|
|
34
|
+
echo_util.echo_http_res(res)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@employee_app.command(
|
|
38
|
+
name='update_employee',
|
|
39
|
+
help='更新员工信息',
|
|
40
|
+
no_args_is_help=True)
|
|
41
|
+
def update_employee(
|
|
42
|
+
employee_id: str = typer.Argument(..., help='员工id'),
|
|
43
|
+
data: str = typer.Argument(..., help='需要更新信息的json字符串')
|
|
44
|
+
):
|
|
45
|
+
data_obj = json.loads(data)
|
|
46
|
+
service = EmployeeService()
|
|
47
|
+
res = service.update_employee(employee_id, data_obj)
|
|
48
|
+
echo_util.echo_http_res(res)
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import typer
|
|
2
|
+
|
|
3
|
+
from app.service.invoice_service import InvoiceService
|
|
4
|
+
from app.util import echo_util
|
|
5
|
+
|
|
6
|
+
invoice_app = typer.Typer()
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@invoice_app.command(
|
|
10
|
+
name='get_sales_invoice_data_list',
|
|
11
|
+
help="获取销项发票列表")
|
|
12
|
+
def get_sales_invoice_data_list(
|
|
13
|
+
uid: str = typer.Option('', '--uid', help='用户uid'),
|
|
14
|
+
current: int = typer.Option(1, '--current', help='页码'),
|
|
15
|
+
invoice_number: str = typer.Option('', '--invoice_number', help='发票号码 关键字,指定发票号码查询,如果为空则查询全部'),
|
|
16
|
+
invoice_date_begin: str = typer.Option('', '--invoice_date_begin', help='发票日期开始 关键字,指定发票日期开始查询(如果要使用,invoice_date_begin和invoice_date_end两个都需要),如果为空则不限制,日期格式为YYYY-MM-DD,例如2024-01-01'),
|
|
17
|
+
invoice_date_end: str = typer.Option('', '--invoice_date_end', help='发票日期结束 关键字,指定发票日期结束查询(如果要使用,invoice_date_begin和invoice_date_end两个都需要),如果为空则不限制,日期格式为YYYY-MM-DD,例如2024-01-31'),
|
|
18
|
+
):
|
|
19
|
+
service = InvoiceService()
|
|
20
|
+
res = service.get_sales_invoice_data_list(uid, current, invoice_number, invoice_date_begin, invoice_date_end)
|
|
21
|
+
echo_util.echo_http_res(res)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@invoice_app.command(
|
|
25
|
+
name='get_income_invoice_data_list',
|
|
26
|
+
help="获取进项/收到的发票列表")
|
|
27
|
+
def get_income_invoice_data_list(
|
|
28
|
+
uid: str = typer.Option('', '--uid', help='用户uid'),
|
|
29
|
+
current: int = typer.Option(1, '--current', help='页码'),
|
|
30
|
+
invoice_number: str = typer.Option('', '--invoice_number', help='发票号码关键字(精确匹配),不传则查询全部'),
|
|
31
|
+
invoice_date_begin: str = typer.Option('', '--invoice_date_begin', help='开票日期开始(YYYY-MM-DD;如需使用需与 invoice_date_end 同时传)'),
|
|
32
|
+
invoice_date_end: str = typer.Option('', '--invoice_date_end', help='开票日期结束(YYYY-MM-DD;如需使用需与 invoice_date_begin 同时传)'),
|
|
33
|
+
status: str = typer.Option('', '--status', help='发票状态(审核中/待确认/已拒绝/已入账),不传则查询全部'),
|
|
34
|
+
):
|
|
35
|
+
service = InvoiceService()
|
|
36
|
+
res = service.get_income_invoice_data_list(uid, current, invoice_number, invoice_date_begin, invoice_date_end, status)
|
|
37
|
+
echo_util.echo_http_res(res)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@invoice_app.command(
|
|
41
|
+
name='set_month_no_sales_invoice',
|
|
42
|
+
help="标记某个月份无销项/开出的发票",
|
|
43
|
+
no_args_is_help=True)
|
|
44
|
+
def set_month_no_sales_invoice(
|
|
45
|
+
uid: str = typer.Option('', '--uid', help='用户uid'),
|
|
46
|
+
year: int = typer.Argument(..., help='年份,如 2026'),
|
|
47
|
+
month: int = typer.Argument(..., help='月份(1-12),如 3'),
|
|
48
|
+
):
|
|
49
|
+
service = InvoiceService()
|
|
50
|
+
res = service.set_month_no_sales_invoice(uid, year, month)
|
|
51
|
+
echo_util.echo_http_res(res)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@invoice_app.command(
|
|
55
|
+
name='set_month_no_invoice',
|
|
56
|
+
help="标记某个月份无进项/收到的发票",
|
|
57
|
+
no_args_is_help=True)
|
|
58
|
+
def set_month_no_invoice(
|
|
59
|
+
uid: str = typer.Option('', '--uid', help='用户uid'),
|
|
60
|
+
year: int = typer.Argument(..., help='年份,如 2026'),
|
|
61
|
+
month: int = typer.Argument(..., help='月份(1-12),如 3'),
|
|
62
|
+
):
|
|
63
|
+
service = InvoiceService()
|
|
64
|
+
res = service.set_month_no_invoice(uid, year, month)
|
|
65
|
+
echo_util.echo_http_res(res)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
@invoice_app.command(
|
|
69
|
+
name='invoice_can_choose_use_list',
|
|
70
|
+
help="进项发票:查询可选用途列表",
|
|
71
|
+
no_args_is_help=True)
|
|
72
|
+
def invoice_can_choose_use_list(
|
|
73
|
+
uid: str = typer.Option('', '--uid', help='用户uid(不传则使用当前已切换在用的 uid)'),
|
|
74
|
+
goods_name: str = typer.Option(..., '--goods_name', help='货物/服务名称(用于推荐用途)'),
|
|
75
|
+
total_tax_price: str = typer.Option(..., '--total_tax_price', help='价税合计(建议传“元”,如 113.00)'),
|
|
76
|
+
total_money: str = typer.Option(..., '--total_money', help='不含税金额(建议传“元”,如 100.00)'),
|
|
77
|
+
):
|
|
78
|
+
service = InvoiceService()
|
|
79
|
+
res = service.invoice_can_choose_use_list(uid, goods_name, total_tax_price, total_money)
|
|
80
|
+
echo_util.echo_http_res(res)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
@invoice_app.command(
|
|
84
|
+
name='invoice_choose_use',
|
|
85
|
+
help="进项发票:选择用途并入账",
|
|
86
|
+
no_args_is_help=True)
|
|
87
|
+
def invoice_choose_use(
|
|
88
|
+
uid: str = typer.Option('', '--uid', help='用户uid(不传则使用当前已切换在用的 uid)'),
|
|
89
|
+
invoice_id: int = typer.Option(..., '--invoice_id', help='发票 id'),
|
|
90
|
+
category: str = typer.Option(..., '--category', help='用途/类目(来自 invoice_can_choose_use_list.items[].id'),
|
|
91
|
+
is_pay: str = typer.Option(..., '--is_pay', help='支付方式(对公银行支付/员工垫付/老板垫付/现金支付)'),
|
|
92
|
+
payee: str = typer.Option(..., '--payee', help='垫付人/收款人(服务端会按支付方式校验)'),
|
|
93
|
+
):
|
|
94
|
+
service = InvoiceService()
|
|
95
|
+
res = service.invoice_choose_use(uid, invoice_id, category, is_pay, payee)
|
|
96
|
+
echo_util.echo_http_res(res)
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import typer
|
|
3
|
+
|
|
4
|
+
from app.service.payroll_service import PayrollService
|
|
5
|
+
from app.util import echo_util
|
|
6
|
+
|
|
7
|
+
payroll_app = typer.Typer()
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def parse_month(month_str: str) -> tuple:
|
|
11
|
+
try:
|
|
12
|
+
parts = month_str.split('-')
|
|
13
|
+
if len(parts) != 2:
|
|
14
|
+
raise typer.BadParameter("格式必须为 yyyy-mm,例如 2026-04")
|
|
15
|
+
year = int(parts[0])
|
|
16
|
+
month_val = int(parts[1])
|
|
17
|
+
if not (1 <= month_val <= 12):
|
|
18
|
+
raise typer.BadParameter("月份必须在 1 到 12 之间")
|
|
19
|
+
return year, month_val
|
|
20
|
+
except ValueError:
|
|
21
|
+
raise typer.BadParameter("年份和月份必须是数字,例如 2026-04")
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@payroll_app.command(
|
|
25
|
+
name='get_payroll',
|
|
26
|
+
help="获取工资单",
|
|
27
|
+
epilog="""使用示例\n\nzjz_cli payroll get_payroll 2026-04""")
|
|
28
|
+
def get_payroll(
|
|
29
|
+
month: str = typer.Argument(..., help='工资单月份,如 2026-04'),
|
|
30
|
+
uid: str = typer.Option('', '--uid', help='公司唯一标识uid')
|
|
31
|
+
):
|
|
32
|
+
req_year, req_month = parse_month(month)
|
|
33
|
+
service = PayrollService()
|
|
34
|
+
res = service.get_payroll(uid, req_year, req_month)
|
|
35
|
+
echo_util.echo_http_res(res)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@payroll_app.command(
|
|
39
|
+
name='get_payroll_creation_status',
|
|
40
|
+
help="获取工资单创建状态",
|
|
41
|
+
no_args_is_help=True)
|
|
42
|
+
def get_payroll_creation_status(
|
|
43
|
+
month: str = typer.Argument(..., help='按月时间,如 2026-04'),
|
|
44
|
+
uid: str = typer.Option('', '--uid', help='公司唯一标识uid')
|
|
45
|
+
):
|
|
46
|
+
req_year, req_month = parse_month(month)
|
|
47
|
+
service = PayrollService()
|
|
48
|
+
res = service.get_payroll_creation_status(uid, req_year, req_month)
|
|
49
|
+
echo_util.echo_http_res(res)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@payroll_app.command(
|
|
53
|
+
name='get_preview_payroll',
|
|
54
|
+
help="获取预览工资单",
|
|
55
|
+
no_args_is_help=True)
|
|
56
|
+
def get_preview_payroll(
|
|
57
|
+
month: str = typer.Argument(..., help='工资单月份,如 2026-04'),
|
|
58
|
+
uid: str = typer.Option('', '--uid', help='公司唯一标识uid')
|
|
59
|
+
):
|
|
60
|
+
req_year, req_month = parse_month(month)
|
|
61
|
+
service = PayrollService()
|
|
62
|
+
res = service.get_preview_payroll(uid, req_year, req_month)
|
|
63
|
+
echo_util.echo_http_res(res)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
@payroll_app.command(
|
|
67
|
+
name='create_payroll',
|
|
68
|
+
help='创建工资单',
|
|
69
|
+
no_args_is_help=True)
|
|
70
|
+
def create_payroll(
|
|
71
|
+
month: str = typer.Argument(..., help='工资单月份,如 2026-04'),
|
|
72
|
+
data: str = typer.Argument(..., help='工资单列表的json字符串'),
|
|
73
|
+
uid: str = typer.Option('', '--uid', help='公司唯一标识uid')
|
|
74
|
+
):
|
|
75
|
+
req_year, req_month = parse_month(month)
|
|
76
|
+
data_obj = json.loads(data)
|
|
77
|
+
service = PayrollService()
|
|
78
|
+
res = service.create_payroll(uid, req_year, req_month, data_obj)
|
|
79
|
+
echo_util.echo_http_res(res)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import typer
|
|
2
|
+
|
|
3
|
+
from app.service.todo_service import TodoService
|
|
4
|
+
from app.util import echo_util
|
|
5
|
+
|
|
6
|
+
todo_app = typer.Typer()
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@todo_app.command(
|
|
10
|
+
name='get_todo_list',
|
|
11
|
+
help="获取代办列表")
|
|
12
|
+
def get_todo_list(
|
|
13
|
+
uid: str = typer.Option('', '--uid', help='公司唯一标识uid(不传则使用当前已切换在用的 uid)'),
|
|
14
|
+
):
|
|
15
|
+
service = TodoService()
|
|
16
|
+
res = service.get_todo_list(uid)
|
|
17
|
+
echo_util.echo_http_res(res)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@todo_app.command(
|
|
21
|
+
name='before_set_month_audited',
|
|
22
|
+
help="提交审账前确认",
|
|
23
|
+
no_args_is_help=True)
|
|
24
|
+
def before_set_month_audited(
|
|
25
|
+
year: int = typer.Argument(..., help='年份,如 2026'),
|
|
26
|
+
month: int = typer.Argument(..., help='月份(1-12),如 3'),
|
|
27
|
+
uid: str = typer.Option('', '--uid', help='公司唯一标识uid(不传则使用当前已切换在用的 uid)'),
|
|
28
|
+
):
|
|
29
|
+
service = TodoService()
|
|
30
|
+
res = service.before_set_month_audited(year, month, uid)
|
|
31
|
+
echo_util.echo_http_res(res)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@todo_app.command(
|
|
35
|
+
name='set_month_audited',
|
|
36
|
+
help="提交审账",
|
|
37
|
+
no_args_is_help=True)
|
|
38
|
+
def set_month_audited(
|
|
39
|
+
year: int = typer.Argument(..., help='年份,如 2026'),
|
|
40
|
+
month: int = typer.Argument(..., help='月份(1-12),如 3'),
|
|
41
|
+
uid: str = typer.Option('', '--uid', help='公司唯一标识uid(不传则使用当前已切换在用的 uid)'),
|
|
42
|
+
):
|
|
43
|
+
service = TodoService()
|
|
44
|
+
res = service.set_month_audited(year, month, uid)
|
|
45
|
+
echo_util.echo_http_res(res)
|