Merge remote-tracking branch 'origin/ps708' into wsc1

This commit is contained in:
王思川 2024-07-09 17:33:07 +08:00
commit 27251c7e21
22 changed files with 17402 additions and 319 deletions

View File

@ -14,6 +14,8 @@ Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import path, include
@ -43,4 +45,4 @@ urlpatterns = [
path("view_data/fin/", include("application.fin_tbl.urls")),
path("view_data/ops/", include("application.ops_tbl.urls")),
path("view_data/busi/", include("application.busi_tbl.urls")),
]
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

File diff suppressed because it is too large Load Diff

View File

@ -148,10 +148,11 @@ class CompanyPoliciesForm(forms.ModelForm):
'publication_date': forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}),
'effective_date': forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}),
'status': forms.Select(attrs={'class': 'form-control'}),
'policy_file': forms.ClearableFileInput(attrs={'class': 'form-control-file'})
}
def __init__(self, *args, **kwargs):
super(CompanyPoliciesForm, self).__init__(*args, **kwargs)
for field_name in self.fields:
self.fields[field_name].required = False
self.fields[field_name].required = False

View File

@ -181,6 +181,7 @@ class CompanyPolicies(models.Model):
('废止', '废止'),
]
status = models.CharField(max_length=20, choices=STATUS_CHOICES, verbose_name='状态', null=True, blank=True)
policy_file = models.FileField(upload_to='policies/', verbose_name='制度文件', null=True, blank=True)
class Meta:
verbose_name = '公司制度表'

View File

@ -0,0 +1,59 @@
{% extends 'items_List.html' %}
{% load static tags %}
{% block fields_list_content %}
<div class="row mb-3">
<div class="col-sm-12">
<div class="card">
<div class="card-body table-border-style">
<div class="table-responsive">
<!-- 表格 开始 -->
<table class="table">
{% get_verbose_field_names_from_model model_config table_exclude_field_name as columns %}
<thead>
<tr>
{% for column in columns %}
<th class="text-center">{{ column }}</th>
{% endfor %}
<th class="text-center">操作</th>
</tr>
</thead>
<tbody id="result" style="color: white;">
{% for item in items %}
<tr>
{% for field in item|get_fields:table_exclude_field_name %}
{% if field.verbose_name == '制度文件' %}
<td class="text-center">
<a href="{{ item.policy_file.url }}" target="_blank">预览文件</a>
</td>
{% else %}
<td class="text-center">{{ field.value|default_if_none:'-' }}</td>
{% endif %}
{% endfor %}
<td class="text-center">
<a href="#" class="edit-btn" data-id="{{ item|get_pk_value }}"
data-bs-toggle="modal" data-bs-target="#addEditModal">编辑</a>
<a href="#"
id="deleteBtn"
class="delete-btn"
style="color: red;"
data-id="{{ item|get_pk_value }}"
data-bs-toggle="modal"
data-bs-target="#deleteModal">删除</a>
</td>
</tr>
{% empty %}
<tr>
<td class="text-center" colspan="{{ columns|length }}">暂无数据</td>
</tr>
{% endfor %}
</tbody>
</table>
<!-- 表格 结束 -->
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -454,7 +454,7 @@ def policies_list_view(request):
"import_excel_button": True
}
return render(request, 'items_list.html', context)
return render(request, 'policy_list.html', context)
@custom_permission_required('cpc_mgnt.add_companypolicies')
@ -463,7 +463,7 @@ def policies_list_add(request):
基础数据-合规管理-公司制度表-添加视图
"""
if request.method == 'POST':
form = CompanyPoliciesForm(request.POST)
form = CompanyPoliciesForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return JsonResponse({"message": "添加成功"})
@ -486,9 +486,9 @@ def policies_list_modify(request):
if request.method == 'POST':
if 'id' in request.POST:
instance = CompanyPolicies.objects.get(policy_id=request.POST['id'])
form = CompanyPoliciesForm(request.POST, instance=instance)
form = CompanyPoliciesForm(request.POST, request.FILES, instance=instance)
else:
form = CompanyPoliciesForm(request.POST)
form = CompanyPoliciesForm(request.POST, request.FILES)
if form.is_valid():
form.save()

View File

@ -1,26 +0,0 @@
{% extends 'items_List.html' %}
{% load static tags %}
{% block js_content %}
<script>
document.getElementById('expense_type').addEventListener('change', function () {
var expenseType = this.value;
var expenseDetailSelect = document.getElementById('expense_detail');
expenseDetailSelect.innerHTML = '<option value="">请选择</option>'; // 清空之前的选项
if (expenseType) {
fetch(`/basic_data/fm/get_expense_details?expense_type=${expenseType}`)
.then(response => response.json())
.then(data => {
data.forEach(function (detail) {
var option = document.createElement('option');
option.value = detail.expense_detail;
option.textContent = detail.expense_detail;
expenseDetailSelect.appendChild(option);
});
})
.catch(error => console.error('Error fetching expense details:', error));
}
});
</script>
{% endblock %}

View File

@ -1,105 +0,0 @@
{% extends 'items_List.html' %}
{% load static tags %}
{% block js_content %}
<script>
document.addEventListener('DOMContentLoaded', function () {
var addItemBtn = document.getElementById('addItemBtn');
var editBtns = document.getElementsByClassName('edit-btn');
var modal = document.getElementById('addEditModal');
function setupModalObserver() {
var observer = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
if (mutation.type === 'childList') {
var projectNameElement = document.getElementById('id_project_name');
if (projectNameElement) {
observer.disconnect(); // 停止观察
// 首先移除已有的事件监听器
projectNameElement.removeEventListener('change', handleProjectNameChange);
// 添加新的事件监听器
projectNameElement.addEventListener('change', handleProjectNameChange);
}
// 监听不含税金额和税率的变化
var amountExcludingTaxElement = document.getElementById('id_amount_excluding_tax');
var taxRateElement = document.getElementById('id_tax_rate');
var taxAmountElement = document.getElementById('id_tax_amount');
var totalAmountElement = document.getElementById('id_total_amount');
if (amountExcludingTaxElement && taxRateElement) {
amountExcludingTaxElement.removeEventListener('input', calculateTaxAndTotal);
taxRateElement.removeEventListener('input', calculateTaxAndTotal);
amountExcludingTaxElement.addEventListener('input', calculateTaxAndTotal);
taxRateElement.addEventListener('input', calculateTaxAndTotal);
}
}
});
});
observer.observe(modal, {
childList: true,
subtree: true
});
}
if (addItemBtn && modal) {
addItemBtn.addEventListener('click', function () {
setupModalObserver();
});
}
if (editBtns && modal) {
Array.from(editBtns).forEach(function (editBtn) {
editBtn.addEventListener('click', function () {
setupModalObserver();
});
});
}
function handleProjectNameChange() {
var projectName = $(this).val();
if (projectName) {
$.ajax({
url: '/basic_data/pjm/project_detail/',
method: 'GET', // 明确指定使用 GET 请求
data: {
'project_name': projectName
},
success: function (data) {
if (data.error) {
alert(data.error);
} else {
$('#id_primary_department').val(data.primary_department);
$('#id_project_manager').val(data.project_leader);
$('#id_nature').val(data.project_nature);
}
},
error: function (xhr, status, error) {
alert('An error occurred: ' + xhr.responseText);
}
});
}
}
function calculateTaxAndTotal() {
var amountExcludingTaxElement = document.getElementById('id_amount_excluding_tax');
var taxRateElement = document.getElementById('id_tax_rate');
var taxAmountElement = document.getElementById('id_tax_amount');
var totalAmountElement = document.getElementById('id_total_amount');
var amountExcludingTax = parseFloat(amountExcludingTaxElement.value) || 0;
var taxRate = parseFloat(taxRateElement.value) || 0;
var taxAmount = amountExcludingTax * (taxRate / 100);
var totalAmount = amountExcludingTax + taxAmount;
taxAmountElement.value = taxAmount.toFixed(2); // 保留两位小数
totalAmountElement.value = totalAmount.toFixed(2); // 保留两位小数
}
});
</script>
{% endblock %}

View File

@ -1,8 +0,0 @@
{% extends 'items_List.html' %}
{% load static tags %}
{% block js_content %}
<script>
</script>
{% endblock %}

View File

@ -342,7 +342,7 @@ def gpb_list_view(request):
"export_url": reverse("export_data"),
"import_excel_button": True
}
return render(request, 'gpb_list_inherit.html', context)
return render(request, 'items_list.html', context)
@custom_permission_required('fac_mgnt.add_groupannualbudget')
@ -995,7 +995,7 @@ def tax_rec_list_view(request):
"export_url": reverse("export_data"),
"import_excel_button": True
}
return render(request, 'tax_rec_list_inherit.html', context)
return render(request, 'items_list.html', context)
@custom_permission_required('fac_mgnt.add_taxrecord')
@ -1264,7 +1264,7 @@ def inv_rec_list_view(request):
"import_excel_button": True,
}
return render(request, 'inv_list_inherit.html', context)
return render(request, 'items_list.html', context)
@custom_permission_required('fac_mgnt.add_invoicerecord')

View File

@ -318,17 +318,10 @@ def emt_list_view(request):
]
},
{
"type": "select",
"type": "year",
"id": "year",
"name": "year",
"label": "年份",
"options": [
{"value": "2024", "display": "2024"},
{"value": "2023", "display": "2023"},
{"value": "2022", "display": "2022"},
{"value": "2021", "display": "2021"},
{"value": "2020", "display": "2020"}
]
}
],
"table_exclude_field_name": ['target_id'],

View File

@ -23,11 +23,20 @@
// 停止观察,防止重复触发
observer.disconnect();
projectNameElement.addEventListener('change', function () {
var projectName = $(this).val();
// 初始化Select2
$(projectNameElement).select2({
placeholder: "选择或搜索项目名称",
allowClear: true,
dropdownParent: $('#addEditModal'),
width: '100%'
});
// 使用Select2监听选择事件
$(projectNameElement).on('select2:select', function (e) {
var projectName = e.params.data.id;
if (projectName) {
$.ajax({
url: '/basic_data/pjm/invoice_detail/', // 确保URL正确
url: '/basic_data/pjm/invoice_detail/',
method: 'GET', // 使用 GET 请求
data: {
'project_name': projectName
@ -40,22 +49,74 @@
yearMonthElement.value = data.year_month;
// 处理项目组员数据
if (data.project_members) {
// 将 input 转换为 select
var select = document.createElement('select');
select.id = nameElement.id;
select.name = nameElement.name;
select.className = nameElement.className;
let nameElementId = nameElement.id;
let nameElementName = nameElement.name;
let nameElementClassName = nameElement.className;
var members = data.project_members.split(', ');
if (data.project_members) {
let currentElement = document.getElementById(nameElementId);
if (!currentElement) {
console.error('Element with id ' + nameElementId + ' not found');
return;
}
if (currentElement.tagName !== 'SELECT') {
// 如果还不是 select则创建新的 select 元素
var select = document.createElement('select');
select.id = nameElementId;
select.name = nameElementName;
select.className = nameElementClassName;
if (currentElement.parentNode) {
currentElement.parentNode.replaceChild(select, currentElement);
} else {
console.error('Parent node not found for element with id ' + nameElementId);
return;
}
currentElement = select;
} else {
// 如果已经是 select清空现有选项
currentElement.innerHTML = '';
}
let members = data.project_members.split(/[,]\s*/);
members.forEach(function (member) {
var option = document.createElement('option');
option.value = member;
option.text = member;
select.appendChild(option);
currentElement.appendChild(option);
});
nameElement.parentNode.replaceChild(select, nameElement);
// 初始化新的Select2
$(currentElement).select2({
placeholder: "选择或搜索项目成员",
allowClear: true,
dropdownParent: $('#addEditModal'),
width: '100%'
});
} else {
// 如果 data.project_members 不存在,将元素恢复为空的 input
let currentElement = document.getElementById(nameElementId);
if (!currentElement) {
console.error('Element with id ' + nameElementId + ' not found');
return;
}
if (currentElement.tagName !== 'INPUT') {
let input = document.createElement('input');
input.id = nameElementId;
input.name = nameElementName;
input.className = nameElementClassName;
input.value = ''; // 设置为空值
if (currentElement.parentNode) {
currentElement.parentNode.replaceChild(input, currentElement);
} else {
console.error('Parent node not found for element with id ' + nameElementId);
return;
}
} else {
// 如果已经是 input只需清空其值
currentElement.value = '';
}
}
}
},

View File

@ -1,3 +1,5 @@
import datetime
from django.http import JsonResponse, Http404
from django.shortcuts import render, get_object_or_404
from django.template.loader import render_to_string
@ -22,7 +24,7 @@ def invoice_detail(request):
if invoice:
data = {
'total_amount': invoice.total_amount,
'year_month': invoice.invoice_date.strftime('%Y-%m'),
'year_month': invoice.invoice_date.strftime('%Y-%m') if invoice.invoice_date else None,
'project_members': project.project_members # 返回项目组员数据
}
return JsonResponse(data)

366
static/css/bootstrap-datepicker.min.css vendored Normal file
View File

@ -0,0 +1,366 @@
/*!
* Datepicker for Bootstrap v1.9.0 (https://github.com/uxsolutions/bootstrap-datepicker)
*
* Licensed under the Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0)
*/
.datepicker {
padding: 4px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
direction: ltr
}
.datepicker-inline {
width: 220px
}
.datepicker-rtl {
direction: rtl
}
.datepicker-rtl.dropdown-menu {
left: auto
}
.datepicker-rtl table tr td span {
float: right
}
.datepicker-dropdown {
top: 0;
left: 0
}
.datepicker-dropdown:before {
content: '';
display: inline-block;
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-bottom: 7px solid #999;
border-top: 0;
border-bottom-color: rgba(0, 0, 0, .2);
position: absolute
}
.datepicker-dropdown:after {
content: '';
display: inline-block;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid #fff;
border-top: 0;
position: absolute
}
.datepicker-dropdown.datepicker-orient-left:before {
left: 6px
}
.datepicker-dropdown.datepicker-orient-left:after {
left: 7px
}
.datepicker-dropdown.datepicker-orient-right:before {
right: 6px
}
.datepicker-dropdown.datepicker-orient-right:after {
right: 7px
}
.datepicker-dropdown.datepicker-orient-bottom:before {
top: -7px
}
.datepicker-dropdown.datepicker-orient-bottom:after {
top: -6px
}
.datepicker-dropdown.datepicker-orient-top:before {
bottom: -7px;
border-bottom: 0;
border-top: 7px solid #999
}
.datepicker-dropdown.datepicker-orient-top:after {
bottom: -6px;
border-bottom: 0;
border-top: 6px solid #fff
}
.datepicker table {
margin: 0;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none
}
.datepicker td, .datepicker th {
text-align: center;
width: 20px;
height: 20px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
border: none
}
.table-striped .datepicker table tr td, .table-striped .datepicker table tr th {
background-color: transparent
}
.datepicker table tr td.day.focused, .datepicker table tr td.day:hover {
background: #eee;
cursor: pointer
}
.datepicker table tr td.new, .datepicker table tr td.old {
color: #999
}
.datepicker table tr td.disabled, .datepicker table tr td.disabled:hover {
background: 0 0;
color: #999;
cursor: default
}
.datepicker table tr td.highlighted {
background: #d9edf7;
border-radius: 0
}
.datepicker table tr td.today, .datepicker table tr td.today.disabled, .datepicker table tr td.today.disabled:hover, .datepicker table tr td.today:hover {
background-color: #fde19a;
background-image: -moz-linear-gradient(to bottom, #fdd49a, #fdf59a);
background-image: -ms-linear-gradient(to bottom, #fdd49a, #fdf59a);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fdd49a), to(#fdf59a));
background-image: -webkit-linear-gradient(to bottom, #fdd49a, #fdf59a);
background-image: -o-linear-gradient(to bottom, #fdd49a, #fdf59a);
background-image: linear-gradient(to bottom, #fdd49a, #fdf59a);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fdd49a', endColorstr='#fdf59a', GradientType=0);
border-color: #fdf59a #fdf59a #fbed50;
border-color: rgba(0, 0, 0, .1) rgba(0, 0, 0, .1) rgba(0, 0, 0, .25);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
color: #000
}
.datepicker table tr td.today.active, .datepicker table tr td.today.disabled, .datepicker table tr td.today.disabled.active, .datepicker table tr td.today.disabled.disabled, .datepicker table tr td.today.disabled:active, .datepicker table tr td.today.disabled:hover, .datepicker table tr td.today.disabled:hover.active, .datepicker table tr td.today.disabled:hover.disabled, .datepicker table tr td.today.disabled:hover:active, .datepicker table tr td.today.disabled:hover:hover, .datepicker table tr td.today.disabled:hover[disabled], .datepicker table tr td.today.disabled[disabled], .datepicker table tr td.today:active, .datepicker table tr td.today:hover, .datepicker table tr td.today:hover.active, .datepicker table tr td.today:hover.disabled, .datepicker table tr td.today:hover:active, .datepicker table tr td.today:hover:hover, .datepicker table tr td.today:hover[disabled], .datepicker table tr td.today[disabled] {
background-color: #fdf59a
}
.datepicker table tr td.today.active, .datepicker table tr td.today.disabled.active, .datepicker table tr td.today.disabled:active, .datepicker table tr td.today.disabled:hover.active, .datepicker table tr td.today.disabled:hover:active, .datepicker table tr td.today:active, .datepicker table tr td.today:hover.active, .datepicker table tr td.today:hover:active {
background-color: #fbf069 \9
}
.datepicker table tr td.today:hover:hover {
color: #000
}
.datepicker table tr td.today.active:hover {
color: #fff
}
.datepicker table tr td.range, .datepicker table tr td.range.disabled, .datepicker table tr td.range.disabled:hover, .datepicker table tr td.range:hover {
background: #eee;
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0
}
.datepicker table tr td.range.today, .datepicker table tr td.range.today.disabled, .datepicker table tr td.range.today.disabled:hover, .datepicker table tr td.range.today:hover {
background-color: #f3d17a;
background-image: -moz-linear-gradient(to bottom, #f3c17a, #f3e97a);
background-image: -ms-linear-gradient(to bottom, #f3c17a, #f3e97a);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f3c17a), to(#f3e97a));
background-image: -webkit-linear-gradient(to bottom, #f3c17a, #f3e97a);
background-image: -o-linear-gradient(to bottom, #f3c17a, #f3e97a);
background-image: linear-gradient(to bottom, #f3c17a, #f3e97a);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f3c17a', endColorstr='#f3e97a', GradientType=0);
border-color: #f3e97a #f3e97a #edde34;
border-color: rgba(0, 0, 0, .1) rgba(0, 0, 0, .1) rgba(0, 0, 0, .25);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0
}
.datepicker table tr td.range.today.active, .datepicker table tr td.range.today.disabled, .datepicker table tr td.range.today.disabled.active, .datepicker table tr td.range.today.disabled.disabled, .datepicker table tr td.range.today.disabled:active, .datepicker table tr td.range.today.disabled:hover, .datepicker table tr td.range.today.disabled:hover.active, .datepicker table tr td.range.today.disabled:hover.disabled, .datepicker table tr td.range.today.disabled:hover:active, .datepicker table tr td.range.today.disabled:hover:hover, .datepicker table tr td.range.today.disabled:hover[disabled], .datepicker table tr td.range.today.disabled[disabled], .datepicker table tr td.range.today:active, .datepicker table tr td.range.today:hover, .datepicker table tr td.range.today:hover.active, .datepicker table tr td.range.today:hover.disabled, .datepicker table tr td.range.today:hover:active, .datepicker table tr td.range.today:hover:hover, .datepicker table tr td.range.today:hover[disabled], .datepicker table tr td.range.today[disabled] {
background-color: #f3e97a
}
.datepicker table tr td.range.today.active, .datepicker table tr td.range.today.disabled.active, .datepicker table tr td.range.today.disabled:active, .datepicker table tr td.range.today.disabled:hover.active, .datepicker table tr td.range.today.disabled:hover:active, .datepicker table tr td.range.today:active, .datepicker table tr td.range.today:hover.active, .datepicker table tr td.range.today:hover:active {
background-color: #efe24b \9
}
.datepicker table tr td.selected, .datepicker table tr td.selected.disabled, .datepicker table tr td.selected.disabled:hover, .datepicker table tr td.selected:hover {
background-color: #9e9e9e;
background-image: -moz-linear-gradient(to bottom, #b3b3b3, grey);
background-image: -ms-linear-gradient(to bottom, #b3b3b3, grey);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#b3b3b3), to(grey));
background-image: -webkit-linear-gradient(to bottom, #b3b3b3, grey);
background-image: -o-linear-gradient(to bottom, #b3b3b3, grey);
background-image: linear-gradient(to bottom, #b3b3b3, grey);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#b3b3b3', endColorstr='#808080', GradientType=0);
border-color: grey grey #595959;
border-color: rgba(0, 0, 0, .1) rgba(0, 0, 0, .1) rgba(0, 0, 0, .25);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
color: #fff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, .25)
}
.datepicker table tr td.selected.active, .datepicker table tr td.selected.disabled, .datepicker table tr td.selected.disabled.active, .datepicker table tr td.selected.disabled.disabled, .datepicker table tr td.selected.disabled:active, .datepicker table tr td.selected.disabled:hover, .datepicker table tr td.selected.disabled:hover.active, .datepicker table tr td.selected.disabled:hover.disabled, .datepicker table tr td.selected.disabled:hover:active, .datepicker table tr td.selected.disabled:hover:hover, .datepicker table tr td.selected.disabled:hover[disabled], .datepicker table tr td.selected.disabled[disabled], .datepicker table tr td.selected:active, .datepicker table tr td.selected:hover, .datepicker table tr td.selected:hover.active, .datepicker table tr td.selected:hover.disabled, .datepicker table tr td.selected:hover:active, .datepicker table tr td.selected:hover:hover, .datepicker table tr td.selected:hover[disabled], .datepicker table tr td.selected[disabled] {
background-color: grey
}
.datepicker table tr td.selected.active, .datepicker table tr td.selected.disabled.active, .datepicker table tr td.selected.disabled:active, .datepicker table tr td.selected.disabled:hover.active, .datepicker table tr td.selected.disabled:hover:active, .datepicker table tr td.selected:active, .datepicker table tr td.selected:hover.active, .datepicker table tr td.selected:hover:active {
background-color: #666 \9
}
.datepicker table tr td.active, .datepicker table tr td.active.disabled, .datepicker table tr td.active.disabled:hover, .datepicker table tr td.active:hover {
background-color: #006dcc;
background-image: -moz-linear-gradient(to bottom, #08c, #04c);
background-image: -ms-linear-gradient(to bottom, #08c, #04c);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#08c), to(#04c));
background-image: -webkit-linear-gradient(to bottom, #08c, #04c);
background-image: -o-linear-gradient(to bottom, #08c, #04c);
background-image: linear-gradient(to bottom, #08c, #04c);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#08c', endColorstr='#0044cc', GradientType=0);
border-color: #04c #04c #002a80;
border-color: rgba(0, 0, 0, .1) rgba(0, 0, 0, .1) rgba(0, 0, 0, .25);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
color: #fff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, .25)
}
.datepicker table tr td.active.active, .datepicker table tr td.active.disabled, .datepicker table tr td.active.disabled.active, .datepicker table tr td.active.disabled.disabled, .datepicker table tr td.active.disabled:active, .datepicker table tr td.active.disabled:hover, .datepicker table tr td.active.disabled:hover.active, .datepicker table tr td.active.disabled:hover.disabled, .datepicker table tr td.active.disabled:hover:active, .datepicker table tr td.active.disabled:hover:hover, .datepicker table tr td.active.disabled:hover[disabled], .datepicker table tr td.active.disabled[disabled], .datepicker table tr td.active:active, .datepicker table tr td.active:hover, .datepicker table tr td.active:hover.active, .datepicker table tr td.active:hover.disabled, .datepicker table tr td.active:hover:active, .datepicker table tr td.active:hover:hover, .datepicker table tr td.active:hover[disabled], .datepicker table tr td.active[disabled] {
background-color: #04c
}
.datepicker table tr td.active.active, .datepicker table tr td.active.disabled.active, .datepicker table tr td.active.disabled:active, .datepicker table tr td.active.disabled:hover.active, .datepicker table tr td.active.disabled:hover:active, .datepicker table tr td.active:active, .datepicker table tr td.active:hover.active, .datepicker table tr td.active:hover:active {
background-color: #039 \9
}
.datepicker table tr td span {
display: block;
width: 23%;
height: 54px;
line-height: 54px;
float: left;
margin: 1%;
cursor: pointer;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px
}
.datepicker table tr td span.focused, .datepicker table tr td span:hover {
background: #eee
}
.datepicker table tr td span.disabled, .datepicker table tr td span.disabled:hover {
background: 0 0;
color: #999;
cursor: default
}
.datepicker table tr td span.active, .datepicker table tr td span.active.disabled, .datepicker table tr td span.active.disabled:hover, .datepicker table tr td span.active:hover {
background-color: #006dcc;
background-image: -moz-linear-gradient(to bottom, #08c, #04c);
background-image: -ms-linear-gradient(to bottom, #08c, #04c);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#08c), to(#04c));
background-image: -webkit-linear-gradient(to bottom, #08c, #04c);
background-image: -o-linear-gradient(to bottom, #08c, #04c);
background-image: linear-gradient(to bottom, #08c, #04c);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#08c', endColorstr='#0044cc', GradientType=0);
border-color: #04c #04c #002a80;
border-color: rgba(0, 0, 0, .1) rgba(0, 0, 0, .1) rgba(0, 0, 0, .25);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
color: #fff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, .25)
}
.datepicker table tr td span.active.active, .datepicker table tr td span.active.disabled, .datepicker table tr td span.active.disabled.active, .datepicker table tr td span.active.disabled.disabled, .datepicker table tr td span.active.disabled:active, .datepicker table tr td span.active.disabled:hover, .datepicker table tr td span.active.disabled:hover.active, .datepicker table tr td span.active.disabled:hover.disabled, .datepicker table tr td span.active.disabled:hover:active, .datepicker table tr td span.active.disabled:hover:hover, .datepicker table tr td span.active.disabled:hover[disabled], .datepicker table tr td span.active.disabled[disabled], .datepicker table tr td span.active:active, .datepicker table tr td span.active:hover, .datepicker table tr td span.active:hover.active, .datepicker table tr td span.active:hover.disabled, .datepicker table tr td span.active:hover:active, .datepicker table tr td span.active:hover:hover, .datepicker table tr td span.active:hover[disabled], .datepicker table tr td span.active[disabled] {
background-color: #04c
}
.datepicker table tr td span.active.active, .datepicker table tr td span.active.disabled.active, .datepicker table tr td span.active.disabled:active, .datepicker table tr td span.active.disabled:hover.active, .datepicker table tr td span.active.disabled:hover:active, .datepicker table tr td span.active:active, .datepicker table tr td span.active:hover.active, .datepicker table tr td span.active:hover:active {
background-color: #039 \9
}
.datepicker table tr td span.new, .datepicker table tr td span.old {
color: #999
}
.datepicker .datepicker-switch {
width: 145px
}
.datepicker .datepicker-switch, .datepicker .next, .datepicker .prev, .datepicker tfoot tr th {
cursor: pointer
}
.datepicker .datepicker-switch:hover, .datepicker .next:hover, .datepicker .prev:hover, .datepicker tfoot tr th:hover {
background: #eee
}
.datepicker .next.disabled, .datepicker .prev.disabled {
visibility: hidden
}
.datepicker .cw {
font-size: 10px;
width: 12px;
padding: 0 2px 0 5px;
vertical-align: middle
}
.input-append.date .add-on, .input-prepend.date .add-on {
cursor: pointer
}
.input-append.date .add-on i, .input-prepend.date .add-on i {
margin-top: 3px
}
.input-daterange input {
text-align: center
}
.input-daterange input:first-child {
-webkit-border-radius: 3px 0 0 3px;
-moz-border-radius: 3px 0 0 3px;
border-radius: 3px 0 0 3px
}
.input-daterange input:last-child {
-webkit-border-radius: 0 3px 3px 0;
-moz-border-radius: 0 3px 3px 0;
border-radius: 0 3px 3px 0
}
.input-daterange .add-on {
display: inline-block;
width: auto;
min-width: 16px;
height: 18px;
padding: 4px 5px;
font-weight: 400;
line-height: 18px;
text-align: center;
text-shadow: 0 1px 0 #fff;
vertical-align: middle;
background-color: #eee;
border: 1px solid #ccc;
margin-left: -5px;
margin-right: -5px
}

1
static/css/select2.min.css vendored Normal file

File diff suppressed because one or more lines are too long

8
static/js/bootstrap-datepicker.min.js vendored Normal file

File diff suppressed because one or more lines are too long

10881
static/js/jquery-3.6.0.js vendored Normal file

File diff suppressed because it is too large Load Diff

2595
static/js/jquery-3.6.0.min.js vendored Normal file

File diff suppressed because it is too large Load Diff

2341
static/js/select2.min.js vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -15,7 +15,8 @@
<link rel="stylesheet" href="{% static 'fonts/fontawesome/css/fontawesome-all.min.css' %}">
<link rel="stylesheet" href="{% static 'plugins/animation/css/animate.min.css' %}">
<link rel="stylesheet" href="{% static 'plugins/prism/css/prism.min.css' %}">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/css/bootstrap-datepicker.min.css">
<link rel="stylesheet" href="{% static 'css/select2.min.css' %}">
<link rel="stylesheet" href="{% static 'css/bootstrap-datepicker.min.css' %}">
<!-- 自定义CSS -->
<link rel="stylesheet" href="{% static 'css/style.css' %}">
@ -106,6 +107,32 @@
color: white;
margin: 0; /* 移除默认的外边距 */
}
.select2-container--default .select2-selection--single {
padding: 10px 16px;
height: 45px; /* 使其与其他表单元素一致 */
border-width: 2px; /* 确保边框样式一致 */
border-radius: 0.375rem; /* 确保边角样式一致 */
background-color: #fff; /* 背景颜色 */
box-shadow: 0 1px 2px 0 rgba(57, 70, 92, 0.05);
}
.select2-container--default .select2-selection--single .select2-selection__rendered {
line-height: 22px; /* 调整行高以确保文本垂直居中 */
}
.select2-container--default .select2-selection--single .select2-selection__arrow {
height: 34px; /* 使箭头高度与选择框一致 */
}
.select2-container .select2-selection--single .select2-selection__rendered {
display: block;
padding-left: 0; /* 确保文本与输入框文本一致 */
}
.select2-container .select2-selection--single {
display: flex;
align-items: center; /* 垂直居中对齐 */
}
.select2-container--default .select2-selection--single .select2-selection__arrow b {
border-color: #555 transparent transparent transparent; /* 修改箭头颜色 */
}
</style>
<!-- 必备JS -->
<script src="{% static 'js/jquery.com_jquery-3.6.0.js' %}"></script>
@ -655,12 +682,14 @@
</body>
<!-- 必备 Js -->
<script src="{% static 'js/jquery-3.6.0.js' %}"></script>
<script src="{% static 'js/vendor-all.min.js' %}"></script>
<script src="{% static 'js/vendor-all.min.js' %}"></script>
<script src="{% static 'plugins/bootstrap/js/popper.min.js' %}"></script>
<script src="{% static 'plugins/bootstrap/js/bootstrap.bundle.min.js' %}"></script>
<script src="{% static 'js/pcoded.min.js' %}"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/js/bootstrap-datepicker.min.js"></script>
<script src="{% static 'js/bootstrap-datepicker.min.js' %}"></script>
<script src="{% static 'js/select2.min.js' %}"></script>
<script>
function showAlert(type, message) {

View File

@ -1,5 +1,5 @@
{% load tags %}
<form id="addEditForm" method="post">
<form id="addEditForm" method="post" enctype="multipart/form-data">
{% csrf_token %}
{% if form.instance.pk %}
<input type="hidden" name="id" value="{{ form.instance.pk }}">
@ -110,6 +110,40 @@
<script type="text/javascript">
$(document).ready(function () {
// 实现项目名称关键字查询和下拉框选择
$('#id_project_name').select2({
placeholder: "选择或搜索项目名称",
allowClear: true,
dropdownParent: $('#addEditModal'),
width: '100%'
});
// 当选择改变时触发的事件
$('#id_project_name').on('select2:select', function (e) {
var projectName = e.params.data.id; // 获取选择的项目名称
if (projectName) {
$.ajax({
url: '/basic_data/pjm/project_detail/',
method: 'GET', // 明确指定使用 GET 请求
data: {
'project_name': projectName
},
success: function (data) {
if (data.error) {
alert(data.error);
} else {
$('#id_primary_department').val(data.primary_department);
$('#id_project_manager').val(data.project_leader);
$('#id_nature').val(data.project_nature);
}
},
error: function (xhr, status, error) {
alert('An error occurred: ' + xhr.responseText);
}
});
}
});
// 一二级部门联动
function updateSecondaryDepartments(primaryDepartment, selectedSecondaryDepartment = null) {
var url = "{% url 'load_secondary_departments' %}";
$.ajax({
@ -126,6 +160,7 @@
});
}
// 监听一级部门变化
$('#id_primary_department').change(function () {
var primaryDepartment = $(this).val();
if (primaryDepartment) {
@ -167,13 +202,7 @@
// 替换现有的#id_seal_type元素
$('#id_seal_type').replaceWith($sealTypeSelect);
// 如果需要在选择时执行某些操作,可以添加监听器
$('#id_seal_type').change(function() {
var selectedSealType = $(this).val();
console.log('选择的用印类型是:' + selectedSealType);
// 在这里添加其他需要的处理逻辑
});
// 使用年相关组件
$('#id_year').datepicker({
format: "yyyy",
viewMode: "years",
@ -181,6 +210,7 @@
autoclose: true
});
// 监听项目类型实现级联选择项目明细
$(document).on('change', '#id_expense_type', function () {
var expenseType = $(this).find("option:selected").text();
var expenseDetailSelect = document.getElementById('id_expense_detail');
@ -201,6 +231,7 @@
}
});
// 纳税记录表-根据纳税频率动态更新纳税所属期
function updateTaxPeriodOptions(taxFrequency, selectedTaxPeriod = null) {
var taxPeriodSelect = document.getElementById('id_tax_period');
taxPeriodSelect.innerHTML = '<option value="">---------</option>'; // 清空之前的选项
@ -235,6 +266,7 @@
}
}
// 监听纳税频率
$(document).on('change', '#id_tax_frequency', function () {
var taxFrequency = this.value;
updateTaxPeriodOptions(taxFrequency);
@ -247,7 +279,7 @@
updateTaxPeriodOptions(initialTaxFrequency, initialTaxPeriod);
}
// 账号运营管理记录-监听所属平台-获取该平台下所有的账号名称
$('#id_platform').change(function () {
var platform = $(this).val();
$.ajax({
@ -266,7 +298,7 @@
});
});
// 合同管理台账
// 合同管理台账-监听合同类别-如为业务类-项目名称可以下拉选择
var $contractType = $('#id_contract_type');
var $projectName = $('#id_project_name');
var $projectNameSelect = $('<select id="id_project_name_select" name="project_name" class="form-control"></select>');
@ -288,6 +320,7 @@
}
});
// 初始化项目名称下拉框
function loadProjects() {
$.ajax({
url: '{% url "get_project_details" %}',
@ -301,6 +334,7 @@
});
}
// 监听项目名称的变化-并且通过项目名称为一级部门和项目负责人赋值
$projectNameSelect.change(function () {
var selectedProject = $(this).val();
if (selectedProject) {
@ -313,8 +347,6 @@
$projectName.val(selectedProject);
$primaryDepartment.val(data.primary_department);
$projectLeader.val(data.project_leader);
// 如果您的表单中有项目性质字段,可以取消下面这行的注释
// $('#id_project_nature').val(data.project_nature);
}
});
}
@ -323,7 +355,7 @@
// 初始化时执行一次
$contractType.trigger('change');
// 客户表
// 客户表-根据是否录入项目信息判断合作项目能否编辑
var $cooperation = $('#id_cooperation');
var $project = $('#id_project');
@ -344,7 +376,7 @@
// 监听 cooperation 字段的变化
$cooperation.change(updateProjectField);
// 固定资产清单
// 固定资产清单-监听入账日期、折旧月份、折旧方法、资产原值、残值、折旧年限、账面价值
var $recordedDate = $('#id_recorded_date');
var $depreciationMonths = $('#id_depreciation_months');
var $depreciationMethod = $('#id_depreciation_method');
@ -354,6 +386,7 @@
var $bookValue = $('#id_book_value');
$depreciationMonths.prop('readonly', true);
// 根据入账日期计算折旧月数
function calculateDepreciationMonths() {
var recordedDate = new Date($recordedDate.val());
var currentDate = new Date();
@ -364,6 +397,7 @@
}
// 计算账面价值=资产原值-(资产原值-残值)*折旧月数/(折旧年限*12
function calculateBookValue() {
var method = $depreciationMethod.val();
if (method === '年限平均法') {
@ -394,5 +428,49 @@
$depreciationYears.change(calculateBookValue);
$depreciationMonths.change(calculateBookValue);
// 开票记录-通过项目名称赋值一级部门、项目负责人、性质
// 监听项目名称变化并实现handleProjectNameChange
// 计算税金和总金额:价税合计金额 = 不含税金额 / 税率; 税额 = 价税合计金额 - 不含税金额
$('#id_amount_excluding_tax, #id_tax_rate').on('input', function () {
var amountExcludingTaxElement = document.getElementById('id_amount_excluding_tax');
var taxRateElement = document.getElementById('id_tax_rate');
var taxAmountElement = document.getElementById('id_tax_amount');
var totalAmountElement = document.getElementById('id_total_amount');
var amountExcludingTax = parseFloat(amountExcludingTaxElement.value) || 0;
var taxRate = parseFloat(taxRateElement.value) || 0;
var taxAmount = amountExcludingTax * (taxRate / 100);
var totalAmount = amountExcludingTax + taxAmount;
taxAmountElement.value = taxAmount.toFixed(2); // 保留两位小数
totalAmountElement.value = totalAmount.toFixed(2); // 保留两位小数
});
// 根据费用类型获取费用明细
document.getElementById('expense_type').addEventListener('change', function () {
var expenseType = this.value;
var expenseDetailSelect = document.getElementById('expense_detail');
expenseDetailSelect.innerHTML = '<option value="">请选择</option>'; // 清空之前的选项
if (expenseType) {
fetch(`/basic_data/fm/get_expense_details?expense_type=${expenseType}`)
.then(response => response.json())
.then(data => {
data.forEach(function (detail) {
var option = document.createElement('option');
option.value = detail.expense_detail;
option.textContent = detail.expense_detail;
expenseDetailSelect.appendChild(option);
});
})
.catch(error => console.error('Error fetching expense details:', error));
}
});
});
</script>

View File

@ -402,6 +402,7 @@
function bindFormSubmit() {
$('#addEditForm').submit(function (e) {
e.preventDefault();
debugger
$.ajax({
url: $(this).attr('action'),
type: 'post',