forked from erp-dev/erp
fix: appversions
This commit is contained in:
@@ -8,6 +8,7 @@ from django.utils import timezone
|
||||
from basic_info import models as basic_models
|
||||
from printing import models as printing_models
|
||||
from settlement import services
|
||||
from stateflow import models as stateflow_models
|
||||
|
||||
|
||||
User = get_user_model()
|
||||
@@ -508,3 +509,308 @@ class GetPlateOrderSummaryByCustomerTestCase(SettlementServiceTestCase):
|
||||
settlement_date='2026-02-08',
|
||||
user=self.user
|
||||
)
|
||||
|
||||
|
||||
class GetPlateOrderSummaryByDesignerTestCase(SettlementServiceTestCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.process = stateflow_models.Process.objects.create(name='开版流程')
|
||||
self.drawing_done = stateflow_models.State.objects.create(name='画图完成')
|
||||
self.color_done = stateflow_models.State.objects.create(name='调色完成')
|
||||
|
||||
def _create_plate_order(self, *, customer=None, plate_date=None, plate_type='首版', production_method='定位'):
|
||||
plate_order = printing_models.PlateOrder.objects.create(
|
||||
merchant=self.merchant,
|
||||
customer=customer or self.customer1,
|
||||
plate_type=plate_type,
|
||||
production_method=production_method,
|
||||
plate_date=timezone.make_aware(datetime.combine(plate_date or self.settlement_date, datetime.min.time())),
|
||||
)
|
||||
business_object = stateflow_models.BusinessObject.objects.create(
|
||||
name=f'PlateOrder-{plate_order.id}',
|
||||
process=self.process,
|
||||
description='',
|
||||
)
|
||||
plate_order.business_object = business_object
|
||||
plate_order.save(update_fields=['business_object'])
|
||||
return plate_order
|
||||
|
||||
def _add_designer_param(self, plate_order, *, designer_name, state=None, cancelled=False):
|
||||
state_log = stateflow_models.StateFlowRecord.objects.create(
|
||||
business_object=plate_order.business_object,
|
||||
state=state or self.drawing_done,
|
||||
completed_by=self.user,
|
||||
is_cancelled=cancelled,
|
||||
)
|
||||
return stateflow_models.StateLogParameterRecord.objects.create(
|
||||
state_log=state_log,
|
||||
parameters={'设计师名称': designer_name},
|
||||
)
|
||||
|
||||
def test_returns_summary_for_drawing_done_designer(self):
|
||||
plate_order = self._create_plate_order()
|
||||
self._add_designer_param(plate_order, designer_name='设计师A')
|
||||
|
||||
result = services.get_plate_order_summary_by_designer(
|
||||
self.merchant.id,
|
||||
self.settlement_date,
|
||||
self.user,
|
||||
)
|
||||
|
||||
self.assertEqual(len(result), 1)
|
||||
self.assertEqual(result[0]['designer_name'], '设计师A')
|
||||
self.assertEqual(result[0]['plate_order_count'][0]['type'], '首版-定位')
|
||||
self.assertEqual(result[0]['plate_order_count'][0]['today'], 1)
|
||||
self.assertEqual(result[0]['plate_order_count'][0]['current_month'], 1)
|
||||
|
||||
def test_defaults_to_drawing_done_only(self):
|
||||
plate_order = self._create_plate_order()
|
||||
self._add_designer_param(plate_order, designer_name='设计师A', state=self.color_done)
|
||||
|
||||
result = services.get_plate_order_summary_by_designer(
|
||||
self.merchant.id,
|
||||
self.settlement_date,
|
||||
self.user,
|
||||
)
|
||||
|
||||
self.assertEqual(result, [])
|
||||
|
||||
|
||||
class GetDesignerWorkflowTaskSummaryTestCase(SettlementServiceTestCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.process = stateflow_models.Process.objects.create(name='开版流程')
|
||||
self.drawing_done = stateflow_models.State.objects.create(name='画图完成')
|
||||
self.color_done = stateflow_models.State.objects.create(name='调色完成')
|
||||
self.drawing_in_progress = stateflow_models.State.objects.create(name='画图中')
|
||||
|
||||
def _create_plate_order(self, *, customer=None, plate_type='首版', production_method='定位'):
|
||||
plate_order = printing_models.PlateOrder.objects.create(
|
||||
merchant=self.merchant,
|
||||
customer=customer or self.customer1,
|
||||
plate_type=plate_type,
|
||||
production_method=production_method,
|
||||
plate_date=timezone.make_aware(datetime.combine(self.settlement_date, datetime.min.time())),
|
||||
)
|
||||
business_object = stateflow_models.BusinessObject.objects.create(
|
||||
name=f'PlateOrder-{plate_order.id}',
|
||||
process=self.process,
|
||||
description='',
|
||||
)
|
||||
plate_order.business_object = business_object
|
||||
plate_order.save(update_fields=['business_object'])
|
||||
return plate_order
|
||||
|
||||
def _create_state_log(self, plate_order, *, state=None, cancelled=False):
|
||||
return stateflow_models.StateFlowRecord.objects.create(
|
||||
business_object=plate_order.business_object,
|
||||
state=state or self.drawing_done,
|
||||
completed_by=self.user,
|
||||
is_cancelled=cancelled,
|
||||
)
|
||||
|
||||
def _add_params(self, state_log, params):
|
||||
return stateflow_models.StateLogParameterRecord.objects.create(
|
||||
state_log=state_log,
|
||||
parameters=params,
|
||||
)
|
||||
|
||||
def _add_designer_param(self, plate_order, *, designer_name, state=None, cancelled=False):
|
||||
state_log = self._create_state_log(
|
||||
plate_order,
|
||||
state=state or self.drawing_done,
|
||||
cancelled=cancelled,
|
||||
)
|
||||
return self._add_params(state_log, {
|
||||
'设计师名称': designer_name,
|
||||
'完成时间': '2026-02-08 10:00:00',
|
||||
})
|
||||
|
||||
def test_sums_task_quantity_by_state_and_type(self):
|
||||
first = self._create_plate_order()
|
||||
second = self._create_plate_order()
|
||||
first_log = self._create_state_log(first, state=self.drawing_done)
|
||||
second_log = self._create_state_log(second, state=self.color_done)
|
||||
self._add_params(first_log, {
|
||||
'设计师名称': '左威',
|
||||
'完成数量': '3',
|
||||
'完成时间': '2026-02-08 10:00:00',
|
||||
})
|
||||
self._add_params(second_log, {
|
||||
'设计师名称': '左威',
|
||||
'完成数量': '2',
|
||||
'完成时间': '2026-02-08 11:00:00',
|
||||
})
|
||||
|
||||
result = services.get_designer_workflow_task_summary(
|
||||
self.merchant.id,
|
||||
self.settlement_date,
|
||||
self.user,
|
||||
state_names=['画图完成', '调色完成'],
|
||||
)
|
||||
|
||||
self.assertEqual(len(result), 1)
|
||||
self.assertEqual(result[0]['designer_name'], '左威')
|
||||
self.assertEqual(result[0]['today'], 5)
|
||||
self.assertEqual(result[0]['current_month'], 5)
|
||||
by_state = {item['state_name']: item for item in result[0]['task_count']}
|
||||
self.assertEqual(by_state['画图完成']['today'], 3)
|
||||
self.assertEqual(by_state['调色完成']['today'], 2)
|
||||
|
||||
def test_default_state_filter_includes_only_done_suffix(self):
|
||||
for state, quantity in [
|
||||
(self.drawing_done, '3'),
|
||||
(self.color_done, '2'),
|
||||
(self.drawing_in_progress, '10'),
|
||||
]:
|
||||
plate_order = self._create_plate_order()
|
||||
state_log = self._create_state_log(plate_order, state=state)
|
||||
self._add_params(state_log, {
|
||||
'设计师名称': '左威',
|
||||
'完成数量': quantity,
|
||||
'完成时间': '2026-02-08 10:00:00',
|
||||
})
|
||||
|
||||
result = services.get_designer_workflow_task_summary(
|
||||
self.merchant.id,
|
||||
self.settlement_date,
|
||||
self.user,
|
||||
)
|
||||
|
||||
self.assertEqual(result[0]['today'], 5)
|
||||
states = {item['state_name'] for item in result[0]['task_count']}
|
||||
self.assertEqual(states, {'画图完成', '调色完成'})
|
||||
|
||||
def test_invalid_quantity_defaults_to_one_and_does_not_dedupe_plate_order(self):
|
||||
plate_order = self._create_plate_order()
|
||||
values = [None, '', '0', '-2', 'bad']
|
||||
for index, value in enumerate(values):
|
||||
state_log = self._create_state_log(plate_order)
|
||||
self._add_params(state_log, {
|
||||
'设计师名称': '左威',
|
||||
'完成数量': value,
|
||||
'完成时间': f'2026-02-08 10:0{index}:00',
|
||||
})
|
||||
|
||||
result = services.get_designer_workflow_task_summary(
|
||||
self.merchant.id,
|
||||
self.settlement_date,
|
||||
self.user,
|
||||
)
|
||||
|
||||
self.assertEqual(result[0]['today'], 5)
|
||||
self.assertEqual(result[0]['current_month'], 5)
|
||||
|
||||
def test_multiple_parameter_records_for_one_state_log_count_once(self):
|
||||
plate_order = self._create_plate_order()
|
||||
state_log = self._create_state_log(plate_order)
|
||||
self._add_params(state_log, {'设计师名称': '左威'})
|
||||
self._add_params(state_log, {
|
||||
'完成数量': '4',
|
||||
'完成时间': '2026-02-08 10:00:00',
|
||||
})
|
||||
|
||||
result = services.get_designer_workflow_task_summary(
|
||||
self.merchant.id,
|
||||
self.settlement_date,
|
||||
self.user,
|
||||
)
|
||||
|
||||
self.assertEqual(result[0]['today'], 4)
|
||||
self.assertEqual(result[0]['current_month'], 4)
|
||||
|
||||
def test_uses_completed_at_when_time_param_missing(self):
|
||||
plate_order = self._create_plate_order()
|
||||
state_log = self._create_state_log(plate_order)
|
||||
completed_at = timezone.make_aware(datetime(2026, 2, 8, 12, 0, 0))
|
||||
stateflow_models.StateFlowRecord.objects.filter(id=state_log.id).update(completed_at=completed_at)
|
||||
state_log.refresh_from_db()
|
||||
self._add_params(state_log, {
|
||||
'设计师名称': '左威',
|
||||
'完成数量': '2',
|
||||
})
|
||||
|
||||
result = services.get_designer_workflow_task_summary(
|
||||
self.merchant.id,
|
||||
self.settlement_date,
|
||||
self.user,
|
||||
)
|
||||
|
||||
self.assertEqual(result[0]['today'], 2)
|
||||
|
||||
def test_filters_cancelled_and_designer_names(self):
|
||||
first = self._create_plate_order()
|
||||
second = self._create_plate_order()
|
||||
cancelled_log = self._create_state_log(first, cancelled=True)
|
||||
kept_log = self._create_state_log(second)
|
||||
self._add_params(cancelled_log, {
|
||||
'设计师名称': '左威',
|
||||
'完成数量': '10',
|
||||
'完成时间': '2026-02-08 10:00:00',
|
||||
})
|
||||
self._add_params(kept_log, {
|
||||
'设计师名称': '王五',
|
||||
'完成数量': '3',
|
||||
'完成时间': '2026-02-08 10:00:00',
|
||||
})
|
||||
|
||||
result = services.get_designer_workflow_task_summary(
|
||||
self.merchant.id,
|
||||
self.settlement_date,
|
||||
self.user,
|
||||
designer_names=['王五'],
|
||||
)
|
||||
|
||||
self.assertEqual(len(result), 1)
|
||||
self.assertEqual(result[0]['designer_name'], '王五')
|
||||
self.assertEqual(result[0]['today'], 3)
|
||||
|
||||
def test_accepts_custom_state_names(self):
|
||||
plate_order = self._create_plate_order()
|
||||
self._add_designer_param(plate_order, designer_name='设计师A', state=self.color_done)
|
||||
|
||||
result = services.get_plate_order_summary_by_designer(
|
||||
self.merchant.id,
|
||||
self.settlement_date,
|
||||
self.user,
|
||||
state_names=['画图完成', '调色完成'],
|
||||
)
|
||||
|
||||
self.assertEqual(len(result), 1)
|
||||
self.assertEqual(result[0]['designer_name'], '设计师A')
|
||||
|
||||
def test_distincts_same_order_same_designer(self):
|
||||
plate_order = self._create_plate_order()
|
||||
self._add_designer_param(plate_order, designer_name='设计师A')
|
||||
self._add_designer_param(plate_order, designer_name='设计师A')
|
||||
|
||||
result = services.get_plate_order_summary_by_designer(
|
||||
self.merchant.id,
|
||||
self.settlement_date,
|
||||
self.user,
|
||||
)
|
||||
|
||||
self.assertEqual(result[0]['plate_order_count'][0]['today'], 1)
|
||||
self.assertEqual(result[0]['plate_order_count'][0]['current_month'], 1)
|
||||
|
||||
def test_applies_customer_visibility(self):
|
||||
other_employee = basic_models.Employee.objects.create(
|
||||
sys_user=User.objects.create_user('designer-other', 'pass123'),
|
||||
merchant=self.merchant,
|
||||
name='其他员工'
|
||||
)
|
||||
invisible_customer = basic_models.Customer.objects.create(
|
||||
merchant=self.merchant,
|
||||
name='不可见客户',
|
||||
created_by=other_employee,
|
||||
)
|
||||
plate_order = self._create_plate_order(customer=invisible_customer)
|
||||
self._add_designer_param(plate_order, designer_name='设计师A')
|
||||
|
||||
result = services.get_plate_order_summary_by_designer(
|
||||
self.merchant.id,
|
||||
self.settlement_date,
|
||||
self.user,
|
||||
)
|
||||
|
||||
self.assertEqual(result, [])
|
||||
|
||||
Reference in New Issue
Block a user