Merge branch 'develop' of https://e.coding.net/ctcdevteam/hberp/hberp into develop

This commit is contained in:
shijing 2022-02-28 15:45:04 +08:00
commit 512549173b
13 changed files with 135 additions and 32 deletions

View File

@ -46,7 +46,7 @@
<template slot-scope="scope">{{ scope.row.order_.number }}</template>
</el-table-column>
<el-table-column label="合同编号" width="110">
<template slot-scope="scope" v-if="scope.row.contract">{{
<template slot-scope="scope" v-if="scope.row.order_">{{
scope.row.order_.contract_.number
}}</template>
</el-table-column>

View File

@ -49,12 +49,12 @@
}}</template>
</el-table-column>
<el-table-column label="合同编号" show-overflow-tooltip width="150">
<template slot-scope="scope">{{
<template slot-scope="scope" v-if=" scope.row.contract_">{{
scope.row.contract_.number
}}</template>
</el-table-column>
<el-table-column label="合同名称" show-overflow-tooltip width="150">
<template slot-scope="scope">{{
<template slot-scope="scope" v-if=" scope.row.contract_">{{
scope.row.contract_.name
}}</template>
</el-table-column>

View File

@ -1,24 +1,39 @@
from __future__ import absolute_import, unicode_literals
from distutils import command
from rest_framework.response import Response
from celery import shared_task
import os
import subprocess
@shared_task
def backup_database():
"""
备份数据库
"""
ret = os.popen('sudo pg_dump -U postgres -d hberp -f /home/lighthouse/hberp_backup.sql')
return Response()
import datetime
name = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
command = '''pg_dump "user=postgres password=zcDsj2021 dbname=hberp" >
/home/lighthouse/backup/hberp_{}.sql'''.format(name)
completed = subprocess.run(command, shell=True, capture_output=True, text=True)
return completed
@shared_task
def reload_server():
os.chdir('/home/lighthouse/hberp')
ret = subprocess.run('sudo git pull && sudo service supervisor reload')
return Response(ret.read())
command = 'sudo git pull && sudo service supervisor reload'
completed = subprocess.run(command, shell=True, capture_output=True, text=True)
return completed
@shared_task
def reload_server_only():
command = 'sudo service supervisor reload'
completed = subprocess.run(command, shell=True, capture_output=True, text=True)
return completed
@shared_task
def backup_media():
command = 'rsync -avu /home/lighthouse/hberp/hb_server/media/ /home/lighthouse/backup/media/'
completed = subprocess.run(command, shell=True, capture_output=True, text=True)
return completed

View File

@ -2,7 +2,7 @@ from django.db.models import base
from rest_framework import urlpatterns
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from apps.develop.views import BackupDatabase, CleanDataView, ReloadServer, UpdateCuttingView, UpdateEquipState, UpdateFIFOItem, UpdateFIFONumber, UpdateLastTestResult, UpdateNeedToOrder, UpdateSpg
from apps.develop.views import BackupDatabase, BackupMedia, CleanDataView, ReloadServer, ReloadServerOnly, UpdateCuttingView, UpdateEquipState, UpdateFIFOItem, UpdateFIFONumber, UpdateLastTestResult, UpdateNeedToOrder, UpdateSpg
urlpatterns = [
path('cleandata/', CleanDataView.as_view()),
@ -15,6 +15,8 @@ urlpatterns = [
path('update_need_to_order/', UpdateNeedToOrder.as_view()),
path('update_fifo_number/', UpdateFIFONumber.as_view()),
path('reload_server/', ReloadServer.as_view()),
path('backup_database/', BackupDatabase.as_view())
path('reload_server_only/', ReloadServerOnly.as_view()),
path('backup_database/', BackupDatabase.as_view()),
path('backup_media/', BackupMedia.as_view())
]

View File

@ -4,7 +4,7 @@ from rest_framework.decorators import permission_classes
from rest_framework.views import APIView
from rest_framework.permissions import IsAdminUser
from rest_framework.response import Response
from apps.develop.tasks import backup_database, reload_server
from apps.develop.tasks import backup_database, backup_media, reload_server, reload_server_only
from apps.inm.models import FIFO, FIFOItem, Inventory, MaterialBatch
from apps.mtm.models import Material
from apps.pm.models import ProductionPlan, SubProductionPlan
@ -13,6 +13,7 @@ from apps.wf.models import Ticket
from apps.wpm.models import Operation, OperationMaterial, WProduct, WproductFlow
from apps.wpm.services import WpmService
from apps.em.tasks import update_equip_state_by_next_check_date
from rest_framework.exceptions import APIException
# Create your views here.
class CleanDataView(APIView):
@ -123,10 +124,47 @@ class UpdateFIFONumber(APIView):
class ReloadServer(APIView):
permission_classes = [IsAdminUser]
def post(self, request):
reload_server()
"""
拉取代码并重启服务
"""
completed = reload_server()
if completed.returncode == 0:
return Response()
else:
raise APIException(completed.stdout)
class ReloadServerOnly(APIView):
permission_classes = [IsAdminUser]
def post(self, request):
"""
仅重启服务
"""
completed = reload_server_only()
if completed.returncode == 0:
return Response()
else:
raise APIException(completed.stdout)
class BackupDatabase(APIView):
permission_classes = [IsAdminUser]
def post(self, request):
backup_database()
"""
备份数据库到指定位置
"""
completed = backup_database()
if completed.returncode == 0:
return Response()
else:
raise APIException(completed.stdout)
class BackupMedia(APIView):
permission_classes = [IsAdminUser]
def post(self, request):
"""
备份资源到指定位置
"""
completed = backup_media()
if completed.returncode == 0:
return Response()
else:
raise APIException(completed.stdout)

View File

@ -0,0 +1,18 @@
# Generated by Django 3.2.9 on 2022-02-28 06:21
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('inm', '0032_auto_20220222_0941'),
]
operations = [
migrations.AddField(
model_name='fifoitem',
name='expiration_date',
field=models.DateField(blank=True, null=True, verbose_name='有效期'),
),
]

View File

@ -105,6 +105,7 @@ class FIFOItem(BaseModel):
batch = models.CharField('批次号', max_length=100, default='')
fifo = models.ForeignKey(FIFO, verbose_name='关联出入库',
on_delete=models.CASCADE)
expiration_date = models.DateField('有效期', null=True, blank=True)
subproduction_plan = models.ForeignKey(
SubProductionPlan, verbose_name='关联子生产计划', on_delete=models.CASCADE, null=True, blank=True)
files = models.ManyToManyField(File, verbose_name='上传材料', blank=True)

View File

@ -80,7 +80,7 @@ class FIFOItemCreateSerializer(serializers.ModelSerializer):
class Meta:
model = FIFOItem
fields = ['warehouse',
'material', 'batch', 'fifo', 'files', 'pu_order_item', 'count']
'material', 'batch', 'fifo', 'files', 'pu_order_item', 'count', 'expiration_date']
def create(self, validated_data):
fifo = validated_data['fifo']
@ -106,7 +106,7 @@ class FIFOItemCreateSerializer(serializers.ModelSerializer):
class FIFOItemUpdateSerializer(serializers.ModelSerializer):
class Meta:
model = FIFOItem
fields = ['warehouse', 'batch', 'files', 'count']
fields = ['warehouse', 'batch', 'files', 'count', 'expiration_date']
class FIFOItemSerializer(serializers.ModelSerializer):
warehouse_ = WareHouseSimpleSerializer(source='warehouse', read_only=True)
@ -128,7 +128,7 @@ class FIFODetailInPurSerializer(serializers.ModelSerializer):
class Meta:
model = FIFOItem
fields = ['material', 'count', 'batch', 'details', 'warehouse']
fields = ['material', 'count', 'batch', 'details', 'warehouse', 'expiration_date']
def validate_batch(self, value):
if value == '':

View File

@ -5,6 +5,8 @@ from apps.mtm.models import Material
from apps.sam.models import SalePack, SaleProduct
from django.db.models import Count
from django.db.models.aggregates import Sum
import logging
logger = logging.getLogger('log')
class InmService:
@classmethod
@ -12,7 +14,8 @@ class InmService:
"""
更新库存(正反)
"""
if instance.type in [FIFO.FIFO_TYPE_PUR_IN, FIFO.FIFO_TYPE_DO_IN]: # 采购入库, 生产入库
if instance.type in [FIFO.FIFO_TYPE_PUR_IN,
FIFO.FIFO_TYPE_DO_IN, FIFO.FIFO_TYPE_OTHER_IN]: # 采购入库, 生产入库, 其他入库
# 更新相关表
for i in FIFOItem.objects.filter(fifo=instance):
material = i.material
@ -21,6 +24,8 @@ class InmService:
o2, _ = MaterialBatch.objects.get_or_create(material=material, warehouse=warehouse, batch=i.batch,\
defaults={'material':material, 'warehouse':warehouse, 'count':0, 'batch':i.batch})
o2.count = o2.count + i.count
if o2.expiration_date is None:
o2.expiration_date = i.expiration_date
o2.save()
iv, _= Inventory.objects.get_or_create(material=material, warehouse=warehouse, \

View File

@ -0,0 +1,19 @@
# Generated by Django 3.2.9 on 2022-02-26 00:35
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('inm', '0032_auto_20220222_0941'),
('sam', '0015_sale_ship_pic'),
]
operations = [
migrations.AddField(
model_name='sale',
name='iproducts',
field=models.ManyToManyField(through='sam.SaleProduct', to='inm.IProduct'),
),
]

View File

@ -94,6 +94,7 @@ class Sale(CommonADModel):
receiver_address = models.CharField('收获地址', null=True, blank=True, max_length=200)
remark = models.CharField('备注', null=True, blank=True, max_length=200)
ship_pic = models.CharField('物流图片', max_length=200, null=True, blank=True)
iproducts = models.ManyToManyField('inm.iproduct', through='sam.saleproduct')
class SaleProduct(BaseModel):
"""

View File

@ -36,7 +36,8 @@ class SaleViewSet(CreateUpdateModelAMixin, ListModelMixin, RetrieveModelMixin, C
elif self.action == 'retrieve':
return SaleListSerializer
return super().get_serializer_class()
@transaction.atomic
def destroy(self, request, *args, **kwargs):
obj = self.get_object()
if obj.is_audited:
@ -161,6 +162,8 @@ class SaleProductViewSet(ListModelMixin, DestroyModelMixin, CreateModelMixin, Ge
})
return Response(SaleProductPackDetailSerializer(instance=obj).data)
elif request.method == 'POST':
if obj.sale.is_audited:
raise exceptions.APIException('该销售记录已审核,不可装箱')
serializer = SaleProductPackSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
vdata = serializer.validated_data
@ -180,6 +183,8 @@ class SaleProductViewSet(ListModelMixin, DestroyModelMixin, CreateModelMixin, Ge
不装箱备注
"""
obj = self.get_object()
if obj.sale.is_audited:
raise exceptions.APIException('该销售记录已审核,不可填写备注')
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
vdata = serializer.validated_data

View File

@ -8,6 +8,7 @@ def get_permission_list(user):
"""
获取权限列表,可用redis存取
"""
perms_list = ['visitor']
if user.is_superuser:
perms_list = ['admin']
else:
@ -43,21 +44,19 @@ class RbacPermission(BasePermission):
perms = cache.get(request.user.username + '__perms')
if not perms:
perms = get_permission_list(request.user)
if perms:
if 'admin' in perms:
return True
elif not hasattr(view, 'perms_map'):
return True
else:
perms_map = view.perms_map
_method = request._request.method.lower()
if perms_map:
for key in perms_map:
if key == _method or key == '*':
if perms_map[key] in perms or perms_map[key] == '*':
return True
return False
if 'admin' in perms:
return True
elif not hasattr(view, 'perms_map'):
return True
else:
perms_map = view.perms_map
_method = request._request.method.lower()
if perms_map:
for key in perms_map:
if key == _method or key == '*':
if perms_map[key] in perms or perms_map[key] == '*':
return True
return False
def has_object_permission(self, request, view, obj):