提交 b1cf94e6 authored 作者: 李思鑫's avatar 李思鑫

新增 康庄大道进销存退报表 产品维度

上级 fdc98e21
......@@ -209,6 +209,8 @@ urlpatterns = [
url(r'^inventory/batch/(?P<obj>\w+)/$',inventory_views.batch_list),
url(r'^inventory/batch/(?P<obj>\w+)/(?P<company_id>\d+)/$',inventory_views.batch_list),
# 产品维度进销存报表
url(r'^inventory/batch/product/(?P<obj>\w+)/$',inventory_views.batch_product_list),
url(r'^inventory/edit/batch/(?P<id>\d+)/$',inventory_views.batch_edit),
......
......@@ -3712,6 +3712,7 @@ def batch_list(request,obj,company_id=None):
dt = datetime.datetime.now().strftime('%Y-%m-%d')
dt_fr = request.GET.get('date_fr', dt)
dt_to = request.GET.get('date_to', dt)
print('dt_fr',dt_fr)
if request.user.company.id == 19257:
dt_fr = request.GET.get(
'date_fr', (datetime.datetime.now() + datetime.timedelta(days=-7)).strftime('%Y-%m-%d'))
......@@ -4315,6 +4316,100 @@ def batch_list(request,obj,company_id=None):
'params': params
})
@login_required
def batch_product_list(request, obj):
company_id=str(request.user.company.id)
ancestor_id = request.user.ancestor_id
product_id = request.GET.get("product_id","")
dt = datetime.datetime.now().strftime('%Y-%m-%d')
dt_fr = request.GET.get('date_fr', dt)
dt_to = request.GET.get('date_to', dt)
# dt_fr = '2023-12-30'
# dt_to = '2024-01-09'
dt_max = max(dt_fr, dt_to)
dt_min = min(dt_fr, dt_to)
dt_fr = dt_min
dt_to = dt_max
params = {
'dt_fr': dt_fr,
'dt_to': dt_to,
# 'product_id': product_id
}
v=None
e=""
sProduct=""
sAgent=""
sCode=""
if product_id:
sProduct=" and product_id="+product_id
# 2022-10-29 stkdetails分表
tb_stk="stkdetails.c"+str(ancestor_id)
vs=Voucher.objects.filter(code=obj.upper())
data=[]
"""
单据类别:voucher id
1;"成品入库单";"GRN";1
2;"销售出库单";"GDN";-1
3;"成品转库单";"GTN";0
4;"销售退库单";"GWN";1
5;"入库单退库";"GCN";-1
"""
if not vs:
e=_('单据类别错误')
else:
v=vs[0]
vid=str(v.id)
sWhere=" where company_id="+company_id+" and vtype_id="+vid+\
" and (dt between '"+dt_fr+"' and '"+dt_to+"')"
package_units = get_package_name(ancestor_id,'数')
clmns=[]
if vid in ['1','2','4']: #成品入库\出库\退库
clmns=['产品名称','生产批次','仓库名称','操作人',package_units[2],package_units[1],package_units[0]]
else:
e=_('暂未开放该类型统计')
s = f"""
select
coalesce((select name from product_product where id=b.product_id),''),
STRING_AGG(DISTINCT b.code,'、') as batch_codes,
STRING_AGG(DISTINCT coalesce((select name from inventory_storehouse where id=b.store_fr_id),''),'、'),
STRING_AGG(DISTINCT coalesce((select coalesce(last_name,username) from company_user where id=b.user_id),''),'、'),
(select json_build_object('x', sum(x), 'h', sum(h), 'p', sum(p))
from
(select
case when label_pkg in (3,4) then 1 else 0 end as x,
case when label_pkg=2 then 1 else 0 end as h,
case when label_pkg=1 then 1 else 0 end as p
from {tb_stk}
WHERE batch_id IN (SELECT UNNEST(array_agg(DISTINCT b.id))) -- 聚合 b.id 成数组
) g
) jdata
from inventory_batch b {sWhere} {sProduct}
group by b.product_id
"""
cur = connection.cursor()
cur.execute(s)
for r in cur.fetchall():
jdata=r[4]
data.append([r[0],r[1],r[2],r[3],
jdata['x'] if jdata['x'] else '0',
jdata['h'] if jdata['h'] else '0',
jdata['p'] if jdata['p'] else '0'
])
return render(request, 'inventory/stock/batch_product_list.html', {
'data':SafeString(data),
'clmns':clmns,
'e': e,
'voucher':v,
'params': params
})
@tj_login_required
def delete_obj(request,obj_name='',id='0'):
......
{% load i18n %}
<!-- 进出存报表 产品维度展示 -->
<style>
#tb tbody .r{
font-weight:bold;
color:red;
}
</style>
<ol class="breadcrumb">
<li> {% trans "进出存报表" %}</li>
<li> {{voucher.name}}统计</li>
</ol>
<script type="text/javascript">
$(document).ready(function(){
$('.datepicker').datepicker({dateFormat: 'yy-mm-dd'});
$('.datepicker').datepicker('setDate',new Date());
setDatePickerZh();
$('#product_label').autocomplete({
source: function(request, response) {
$.ajax({
url: '/obj/ajax/autocomplete/product/',
dataType: "json",
data: {
term: $("#product_label").val() ,//搜索栏里的内容
//company_id: $('#id_company').val() ,//额外参数
},
success: function(data) {
response(data);
}
});
},
select: function (event, ui) {
$("#product_id").val(ui.item.value);
$("#product_label").val(ui.item.label);
return false;
}
});
$('#agent_label').autocomplete({
source: function(request, response) {
$.ajax({
url: '/obj/ajax/autocomplete/agent/',
dataType: "json",
data: {
term: $("#agent_label").val() ,//搜索栏里的内容
//company_id: $('#id_company').val() ,//额外参数
},
success: function(data) {
response(data);
}
});
},
select: function (event, ui) {
$("#agent_id").val(ui.item.value);
$("#agent_label").val(ui.item.label);
return false;
}
});
$('.btn-qry').click(function(){
var product_id='',agent_id='',code='',batch_no='';
if (!$.isEmpty($('#product_id').val())){
product_id=$('#product_id').val();
};
if (!$.isEmpty($('#agent_id').val())){
agent_id=$('#agent_id').val();
};
if (!$.isEmpty($('#code').val())){
code=$('#code').val();
};
if (!$.isEmpty($('#batch_no').val())){
batch_no=$('#batch_no').val();
};
date_fr=$('#dt_fr').val();
date_to=$('#dt_to').val();
var params=[];
if(product_id!=''){
params.push('product_id='+product_id);
params.push('product_label='+$('#product_label').val());
};
if(agent_id!=''){
params.push('agent_id='+agent_id);
params.push('agent_label='+$('#agent_label').val());
};
if(code!=''){
params.push('code='+code);
};
if(date_fr!=''){params.push('date_fr='+date_fr)};
if(date_to!=''){params.push('date_to='+date_to)};
//2024-03-19
if(batch_no!=''){params.push('batch_no='+batch_no)};
if(params.length==0){
bootbox.alert("{% trans '请先输入查询条件!'%}");
}else{
$.RefreshContent('{{request.path}}?'+params.join('&'));
}
});
{% ifnotequal params.dt_fr '' %}
$('#dt_fr').val('{{params.dt_fr}}');
{% endifnotequal %}
{% ifnotequal params.dt_to '' %}
$('#dt_to').val('{{params.dt_to}}');
{% endifnotequal %}
{% ifnotequal params.product_id '' %}
$('#product_id').val('{{params.product_id}}');
$("#product_label").val('{{params.product_label}}');
{% endifnotequal %}
{% ifnotequal params.agent_id '' %}
$('#agent_id').val('{{params.agent_id}}');
$("#agent_label").val('{{params.agent_label}}');
{% endifnotequal %}
{% ifnotequal params.batch_no '' %}
$('#batch_no').val('{{params.batch_no}}');
{% endifnotequal %}
var table=$('#tb').DataTable({
//"lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]],
//"bLengthChange":true,
dom: 'Bfrtip',
autoWidth: false,
buttons: [{extend:'excelHtml5',text:'导出到Excel'}],
language:lng,
data:{{data}},
{% ifequal 1 request.user.id %}
createdRow: function( nRow, aData, iDataIndex ) {
var s='',html='';
s=aData[10];
switch(s){
case '单号异常':
html='<span style="color:red">单号异常</span>';
break;
case '客户异常':
html='<button class="btn btn-order btn-danger btn-xs">客户异常</button>';
break;
default:
html=s;
break;
};
$('td:eq(10)', nRow).html(html);
}
{% endifequal %}
});
table.columns().every( function () {
var that = this;
$('input', this.footer() ).on( 'keyup change clear', function () {
if ( that.search() !== this.value ) {
that.search( this.value ).draw();
}
});
});
$('#tb').on("click","td a",function(event){
$(event.target.parentNode).addClass('row_selected');
event.preventDefault();
$.OpenDlg($(this).attr('href'),'订单{{voucher.name}}-明细列表',1000,700);
});
$('#tb').on("click","td .btn-order",function(event){
var code=$(this).closest('tr').children().eq(1).text();
$.ajax({
url:'/inventory/batch/query/?dn_number='+code,
success:function (data){
$('#dlg-order .modal-title').text('发货单详情 '+code);
$('#order-tm').text(data.tm);
$('#customer-code').text(data.customer.code);
$('#customer-name').text(data.customer.name);
var html='';
for( var i in data.products){
html=html+'<tr>'+
'<td>'+data.products[i].code+'</td>'+
'<td>'+data.products[i].name+'</td>'+
'<td>'+data.products[i].qty+'</td>'+
'</tr>';
};
$('#order_tb tbody').html(html);
$('#dlg-order').modal('show');
}
});
//inventory/batch/query/?dn_number=8220110011
//$(event.target.parentNode).addClass('row_selected');
//event.preventDefault();
//$.OpenDlg($(this).attr('href'),'订单{{voucher.name}}-明细列表',1000,700);
});
});
function catDetails(ele){
var batch_id = $(ele).parent().parent().children().find('a').attr('href').split("/")[4]
$.ajax({
url:'/inventory/batchno/details/'+batch_id+'/',
success:function (res){
$('#batch_tb').DataTable({
//"lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]],
//"bLengthChange":true,
dom: 'Bfrtip',
autoWidth: false,
destroy:true,
buttons: [{extend:'excelHtml5',text:'导出到Excel'}],
language:lng,
data:res.details
});
$('#modal1').modal('show')
}
})
}
function deleteItem(id){
var r = confirm('您确定要限制该批次出奖吗?');
if(r){
var durl = '/inventory/GDN/pc_lottery/'+id+'/'
$.RefreshContent(durl);
}
}
</script>
<form role="form" class="form-inline" style="margin-top:0px;">
<div class="col-sm-2 input-group">
<span class="input-group-addon">{% trans "开始日期"%}</span>
<input class="datepicker form-control" id="dt_fr" />
</div>
<div class="col-sm-2 input-group">
<span class="input-group-addon">{% trans "结束日期"%}</span>
<input class="datepicker form-control" id="dt_to" />
</div>
{% ifequal user.company.level_id 1 %}
<!-- <div class="col-sm-2 input-group">
<input class="form-control" id="batch_no" placeholder='所有单号' />
</div> -->
<div class="col-sm-2 input-group">
<input class="form-control" id="product_label" placeholder='所有产品' />
<input type='hidden' id='product_id' />
</div>
<!-- {% ifequal voucher.id 2 %}
<div class="col-sm-2 input-group">
<input class="form-control" id="agent_label" placeholder='所有经销商' />
<input type='hidden' id='agent_id' />
</div>
{% endifequal %}
{% ifequal voucher.id 1 %}
<div class="col-sm-2 input-group">
<input class="form-control" id="code" placeholder='所有生产批次' />
</div>
{% endifequal %} -->
{% endifequal %}
<div style="float:right;">
<span class='input-group-btn'>
<a type="button" class='btn btn-primary btn-qry'>
<span class='glyphicon glyphicon-search' style='padding-right:5px;'></span>{% trans '查找' %}
</a>
</span>
</div>
</form>
<div class="clearfix"></div>
<div id="inventory-list" class="table-responsive">
<div class='x_panel'>
<table id="tb" class="table table-striped table-bordered dt-responsive" width="100%" >
<thead><tr>
{% for c in clmns %}
<th>{{c}}</th>
{% endfor %}
</tr></thead>
<tbody></tbody>
<tfoot>
{% for c in clmns %}
<th><input type="text" placeholder="{{c}}"></th>
{% endfor %}
</tfoot>
</table>
</div>
</div>
<div class="modal fade" tabindex="-1" role="dialog" id="modal1">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span>
</button>
<h4 class="modal-title">批次详情</h4>
</div>
<div class="modal-body">
<table id="batch_tb" class="table table-striped table-bordered dt-responsive" width="100%" >
<thead>
<tr>
<th>批次编号</th>
<th>入库时间</th>
<th>到期天数</th>
<th>到期时间</th>
<th>数量</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<div class="modal fade" tabindex="-1" role="dialog" id="dlg-order">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span>
</button>
<h4 class="modal-title"></h4>
</div>
<div class="modal-body">
<div style='margin-bottom:5px;'>
客户编码:<span id='customer-code' style='color:green'></span>
客户名称:<span id='customer-name' style='color:green'></span>
单据时间:<span id='order-tm' style='color:green'></span>
</div>
<table id="order_tb" class="table table-striped table-bordered dt-responsive" width="100%" >
<thead>
<tr>
<th>产品编码</th>
<th>产品名称</th>
<th>发货数量</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论