Исправил закрытие сделки. добавил черновик страницы для списания в 1С
All checks were successful
Deploy MES Core / deploy (push) Successful in 13s
All checks were successful
Deploy MES Core / deploy (push) Successful in 13s
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timedelta
|
||||
from urllib.parse import urlsplit
|
||||
|
||||
import os
|
||||
@@ -32,7 +32,21 @@ from warehouse.services.transfers import receive_transfer
|
||||
from shiftflow.services.closing import apply_closing
|
||||
|
||||
from .forms import ProductionTaskCreateForm
|
||||
from .models import Company, Deal, DxfPreviewJob, DxfPreviewSettings, EmployeeProfile, Item, Machine, ProductionTask
|
||||
from .models import (
|
||||
Company,
|
||||
CuttingSession,
|
||||
Deal,
|
||||
DxfPreviewJob,
|
||||
DxfPreviewSettings,
|
||||
EmployeeProfile,
|
||||
Item,
|
||||
Machine,
|
||||
ProductionReportConsumption,
|
||||
ProductionReportRemnant,
|
||||
ProductionReportStockResult,
|
||||
ProductionTask,
|
||||
ShiftItem,
|
||||
)
|
||||
|
||||
|
||||
def _get_dxf_preview_settings() -> DxfPreviewSettings:
|
||||
@@ -1427,7 +1441,7 @@ class WarehouseStocksView(LoginRequiredMixin, TemplateView):
|
||||
ctx['start_date'] = start_date
|
||||
ctx['end_date'] = end_date
|
||||
|
||||
qs = StockItem.objects.select_related('location', 'material', 'material__category', 'entity', 'deal').all()
|
||||
qs = StockItem.objects.select_related('location', 'material', 'material__category', 'entity', 'deal').filter(is_archived=False)
|
||||
if ship_loc_id:
|
||||
qs = qs.exclude(location_id=ship_loc_id)
|
||||
|
||||
@@ -1681,7 +1695,8 @@ class ClosingView(LoginRequiredMixin, TemplateView):
|
||||
if work_location_id:
|
||||
stock_items = list(
|
||||
StockItem.objects.select_related('location', 'material')
|
||||
.filter(location_id=work_location_id, material_id=int(material_id), entity__isnull=True)
|
||||
.filter(location_id=work_location_id, material_id=int(material_id), entity__isnull=True, is_archived=False)
|
||||
.filter(quantity__gt=0)
|
||||
.order_by('created_at', 'id')
|
||||
)
|
||||
|
||||
@@ -1784,6 +1799,116 @@ class ClosingView(LoginRequiredMixin, TemplateView):
|
||||
messages.error(request, 'Выбери хотя бы один пункт сменки и режим закрытия (полностью/частично).')
|
||||
return redirect(f"{reverse_lazy('closing')}?machine_id={machine_id}&material_id={material_id}")
|
||||
|
||||
|
||||
class WriteOffsView(LoginRequiredMixin, TemplateView):
|
||||
template_name = 'shiftflow/writeoffs.html'
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
profile = getattr(request.user, 'profile', None)
|
||||
role = profile.role if profile else ('admin' if request.user.is_superuser else 'operator')
|
||||
if role not in ['admin', 'clerk', 'observer']:
|
||||
return redirect('registry')
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
ctx = super().get_context_data(**kwargs)
|
||||
|
||||
profile = getattr(self.request.user, 'profile', None)
|
||||
role = profile.role if profile else ('admin' if self.request.user.is_superuser else 'operator')
|
||||
ctx['user_role'] = role
|
||||
ctx['can_edit'] = role in ['admin', 'clerk']
|
||||
|
||||
start_date = (self.request.GET.get('start_date') or '').strip()
|
||||
end_date = (self.request.GET.get('end_date') or '').strip()
|
||||
reset = self.request.GET.get('reset')
|
||||
|
||||
if not start_date or not end_date or reset:
|
||||
today = timezone.localdate()
|
||||
start = today - timedelta(days=21)
|
||||
start_date = start.strftime('%Y-%m-%d')
|
||||
end_date = today.strftime('%Y-%m-%d')
|
||||
|
||||
ctx['start_date'] = start_date
|
||||
ctx['end_date'] = end_date
|
||||
|
||||
reports_qs = (
|
||||
CuttingSession.objects.select_related('machine', 'operator')
|
||||
.filter(is_closed=True, date__gte=start_date, date__lte=end_date)
|
||||
.order_by('-date', '-id')
|
||||
)
|
||||
|
||||
reports = list(
|
||||
reports_qs.prefetch_related(
|
||||
'tasks__task__deal',
|
||||
'tasks__task__material',
|
||||
'consumptions__material',
|
||||
'consumptions__stock_item__material',
|
||||
'results__stock_item__material',
|
||||
'results__stock_item__entity',
|
||||
)
|
||||
)
|
||||
|
||||
report_cards = []
|
||||
for r in reports:
|
||||
consumed = {}
|
||||
for c in list(getattr(r, 'consumptions', []).all() if hasattr(getattr(r, 'consumptions', None), 'all') else []):
|
||||
mat = None
|
||||
if getattr(c, 'material_id', None):
|
||||
mat = c.material
|
||||
elif getattr(c, 'stock_item_id', None) and getattr(c.stock_item, 'material_id', None):
|
||||
mat = c.stock_item.material
|
||||
|
||||
label = str(mat) if mat else '—'
|
||||
key = getattr(mat, 'id', None) or label
|
||||
consumed[key] = consumed.get(key, 0.0) + float(c.quantity)
|
||||
|
||||
produced = {}
|
||||
remnants = {}
|
||||
for res in list(getattr(r, 'results', []).all() if hasattr(getattr(r, 'results', None), 'all') else []):
|
||||
si = res.stock_item
|
||||
if res.kind == 'finished':
|
||||
label = str(getattr(si, 'entity', None) or '—')
|
||||
produced[label] = produced.get(label, 0.0) + float(si.quantity)
|
||||
elif res.kind == 'remnant':
|
||||
label = str(getattr(si, 'material', None) or '—')
|
||||
remnants[label] = remnants.get(label, 0.0) + float(si.quantity)
|
||||
|
||||
report_cards.append({
|
||||
'report': r,
|
||||
'consumed': consumed,
|
||||
'produced': produced,
|
||||
'remnants': remnants,
|
||||
'tasks': list(getattr(r, 'tasks', []).all() if hasattr(getattr(r, 'tasks', None), 'all') else []),
|
||||
})
|
||||
|
||||
ctx['report_cards'] = report_cards
|
||||
|
||||
items_qs = (
|
||||
Item.objects.select_related('task', 'task__deal', 'machine')
|
||||
.filter(status__in=['done', 'partial'], date__gte=start_date, date__lte=end_date)
|
||||
.order_by('-date', '-id')
|
||||
)
|
||||
ctx['items'] = list(items_qs)
|
||||
return ctx
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
profile = getattr(request.user, 'profile', None)
|
||||
role = profile.role if profile else ('admin' if request.user.is_superuser else 'operator')
|
||||
if role not in ['admin', 'clerk']:
|
||||
return redirect('writeoffs')
|
||||
|
||||
ids = request.POST.getlist('item_ids')
|
||||
item_ids = [int(x) for x in ids if x.isdigit()]
|
||||
if not item_ids:
|
||||
messages.error(request, 'Не выбрано ни одного сменного задания.')
|
||||
return redirect('writeoffs')
|
||||
|
||||
Item.objects.filter(id__in=item_ids).update(is_synced_1c=True)
|
||||
messages.success(request, f'Отмечено в 1С: {len(item_ids)}.')
|
||||
start_date = (request.POST.get('start_date') or '').strip()
|
||||
end_date = (request.POST.get('end_date') or '').strip()
|
||||
return redirect(f"{reverse_lazy('writeoffs')}?start_date={start_date}&end_date={end_date}")
|
||||
|
||||
if not consumptions:
|
||||
messages.error(request, 'Заполни списание: укажи, какие единицы на складе использованы и в каком количестве.')
|
||||
return redirect(f"{reverse_lazy('closing')}?machine_id={machine_id}&material_id={material_id}")
|
||||
|
||||
Reference in New Issue
Block a user