diff --git a/hb_client/src/views/pm/management.vue b/hb_client/src/views/pm/management.vue
index 5a2df27..caa5cb6 100644
--- a/hb_client/src/views/pm/management.vue
+++ b/hb_client/src/views/pm/management.vue
@@ -46,7 +46,7 @@
{{ scope.row.order_.number }}
- {{
+ {{
scope.row.order_.contract_.number
}}
diff --git a/hb_client/src/views/pm/resources.vue b/hb_client/src/views/pm/resources.vue
index c29f641..4b433cc 100644
--- a/hb_client/src/views/pm/resources.vue
+++ b/hb_client/src/views/pm/resources.vue
@@ -49,12 +49,12 @@
}}
- {{
+ {{
scope.row.contract_.number
}}
- {{
+ {{
scope.row.contract_.name
}}
diff --git a/hb_server/apps/develop/tasks.py b/hb_server/apps/develop/tasks.py
index a7345dc..c167aad 100644
--- a/hb_server/apps/develop/tasks.py
+++ b/hb_server/apps/develop/tasks.py
@@ -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
\ No newline at end of file
diff --git a/hb_server/apps/develop/urls.py b/hb_server/apps/develop/urls.py
index c9acf54..66a21a5 100644
--- a/hb_server/apps/develop/urls.py
+++ b/hb_server/apps/develop/urls.py
@@ -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())
]
diff --git a/hb_server/apps/develop/views.py b/hb_server/apps/develop/views.py
index 0cad10c..bdd9b07 100644
--- a/hb_server/apps/develop/views.py
+++ b/hb_server/apps/develop/views.py
@@ -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()
\ No newline at end of file
+ """
+ 备份数据库到指定位置
+ """
+ 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)
\ No newline at end of file
diff --git a/hb_server/apps/inm/migrations/0033_fifoitem_expiration_date.py b/hb_server/apps/inm/migrations/0033_fifoitem_expiration_date.py
new file mode 100644
index 0000000..9486151
--- /dev/null
+++ b/hb_server/apps/inm/migrations/0033_fifoitem_expiration_date.py
@@ -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='有效期'),
+ ),
+ ]
diff --git a/hb_server/apps/inm/models.py b/hb_server/apps/inm/models.py
index 4053765..2d74d11 100644
--- a/hb_server/apps/inm/models.py
+++ b/hb_server/apps/inm/models.py
@@ -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)
diff --git a/hb_server/apps/inm/serializers.py b/hb_server/apps/inm/serializers.py
index d033aaa..4c2374f 100644
--- a/hb_server/apps/inm/serializers.py
+++ b/hb_server/apps/inm/serializers.py
@@ -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 == '':
diff --git a/hb_server/apps/inm/services.py b/hb_server/apps/inm/services.py
index 8be61b7..49c7c58 100644
--- a/hb_server/apps/inm/services.py
+++ b/hb_server/apps/inm/services.py
@@ -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, \
diff --git a/hb_server/apps/sam/migrations/0016_sale_iproducts.py b/hb_server/apps/sam/migrations/0016_sale_iproducts.py
new file mode 100644
index 0000000..00c6f8d
--- /dev/null
+++ b/hb_server/apps/sam/migrations/0016_sale_iproducts.py
@@ -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'),
+ ),
+ ]
diff --git a/hb_server/apps/sam/models.py b/hb_server/apps/sam/models.py
index ba9a809..12ef0a8 100644
--- a/hb_server/apps/sam/models.py
+++ b/hb_server/apps/sam/models.py
@@ -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):
"""
diff --git a/hb_server/apps/sam/views_sale.py b/hb_server/apps/sam/views_sale.py
index ed18874..1889abc 100644
--- a/hb_server/apps/sam/views_sale.py
+++ b/hb_server/apps/sam/views_sale.py
@@ -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
diff --git a/hb_server/apps/system/permission.py b/hb_server/apps/system/permission.py
index bcb94ac..7b218d3 100644
--- a/hb_server/apps/system/permission.py
+++ b/hb_server/apps/system/permission.py
@@ -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):