import os import django import sys from decimal import Decimal from django.db import transaction from django.db.models import F import unittest from datetime import datetime, timedelta def setup_django(): """设置Django环境""" project_path = "D:/Document/code/vue/greater_wms" sys.path.append(project_path) os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'greaterwms.settings') django.setup() print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] Django环境已设置") def reconcile_material_history(): """从后往前修复物料变动历史记录""" from container.models import MaterialStatistics, MaterialChangeHistory # 获取所有物料统计 all_materials = MaterialStatistics.objects.all() for material in all_materials: # 获取该物料的所有变动历史记录(按时间倒序) print(f"处理物料 {material.goods_code} 的变动历史记录...") print(f"获取物料 {material.goods_code} 的所有变动历史记录...") history_records = MaterialChangeHistory.objects.filter( goods_code = material.goods_code ).order_by('-change_time') if not history_records.exists(): continue print(f"总计获取到 {history_records.count()} 条{material.goods_code}历史记录") # 从物料统计中获取当前库存作为最后一个记录的期末数量 current_quantity = material.total_quantity # 从后往前处理每个历史记录 for i, record in enumerate(history_records): if record.count_time >= 0: # 最后一个记录:使用当前库存作为期末数量 if i == 0: record.closing_quantity = current_quantity else: # 前一个记录的期末数量就是当前记录的期初数量 record.closing_quantity = history_records[i-1].opening_quantity # 计算期初数量(期末 + 出库 - 入库) record.in_quantity = record.batch_log.goods_in_qty record.out_quantity = record.batch_log.goods_out_qty record.opening_quantity = ( record.closing_quantity + record.out_quantity - record.in_quantity ) # 更新当前数量为当前记录的期初数量(用于下一个记录) current_quantity = record.opening_quantity print(f"更新记录 {record.id},条目时间{record.change_time}: 期初 {record.opening_quantity}, 期末 {record.closing_quantity}, 入库 {record.in_quantity}, 出库 {record.out_quantity}") # 更新记录 record.count_time = 1 record.save() # 验证第一个记录的期初数量是否合理 first_record = history_records.last() if first_record.opening_quantity < 0: print(f"警告:物料 {material.goods_code} 的期初库存为负值: {first_record.opening_quantity}") # # 更新物料统计的总库存(应该与最后一个记录的期末数量一致) # material.total_quantity = history_records.first().closing_quantity # material.save() print("物料变动历史记录修复完成") def main(): """主测试函数""" setup_django() print("\n===== 开始物料历史记录修复测试 =====") try: reconcile_material_history() except Exception as e: print(f"\n❌ 测试异常: {e}") import traceback traceback.print_exc() finally: # 清理测试数据 print("\n===== 测试结束 =====") if __name__ == "__main__": main()