
InvenTree 采购管理模块全解析采购订单、供应商与制造商部分实战指南【免费下载链接】InvenTreeOpen Source Inventory Management System项目地址: https://gitcode.com/GitHub_Trending/in/InvenTree采购Purchasing是 InvenTree 开源库存管理系统中将“外部购入”转化为“库存资产”的核心环节。本篇以官方采购文档 docs/docs/purchasing/index.md 为主体结合其子文档 采购订单、供应商、制造商并对照order与company应用的源码实现完整讲解采购订单生命周期、供应商部分与制造商部分的管理方式、收货入库流程以及全部相关全局设置。读完本文你将能够熟练完成从创建供应商、关联供应商部分、下达采购订单到收货入库的完整采购闭环并理解其背后的状态机与数据模型逻辑。采购系统概览InvenTree 提供了一套完整的采购Purchasing体系用来简化采购流程、管理供应商并跟踪采购订单。其设计目标在于无缝地控制外部物料向 InvenTree 数据库的流入ingestion确保所有部件在整个生命周期内都被正确记账与追踪。整个采购体系由三个核心概念构成它们也是采购模块的三级结构采购订单Purchase Order, PO向供应商提出的、要求提供特定部件或材料的正式请求是采购流程的核心载体供应商部分Supplier Part从外部供应商采购的单个可购条目可与 InvenTree 数据库中的部件Part绑定制造商部分Manufacturer Part由特定制造商生产、可能同时由多个供应商销售的部件。在 订单数据模型 中PurchaseOrder类继承了Order抽象基类与TotalPriceMixin其get_absolute_url指向/purchasing/purchase-order/{pk}这也印证了采购模块是围绕「订单order— 行项目line items— 供应商部分supplier part」三层关系建模的。供应商Suppliers供应商Supplier本质上是一种被标记为外部部件/原材料销售方的 公司Company 记录。在模型层面PurchaseOrder.supplier字段通过limit_choices_to{is_supplier: True}见 order/models.py来约束——只有启用了 Supplier 属性的公司才能被选为采购订单的供应商。访问供应商页面点击主导航栏中的Buy购物车图标标签页在下拉列表中选择Suppliers大楼图标选项即可进入供应商列表页面。权限要求查看、添加、编辑和删除供应商都需要相应的 采购订单用户权限。添加供应商在供应商页面点击New Supplier加号图标按钮会打开 Create new Supplier 表单。填写供应商信息其中Company name和Company description为必填项后点击Submit提交即可。供应商 vs 制造商如果该供应商本身就是直接面向客户销售的制造商可以在提交表单前勾选is manufacturer复选框也可以在之后随时开启。从源码角度看「供应商」只是 Company 模型 上的布尔属性组合采购功能实际依赖的是SupplierPart供应商部分这一数据对象。供应商部分Supplier Parts供应商部分是链接到某个供应商、被定义为「可采购项目」的记录。每个供应商部分通过 SKU供应商部件号唯一标识并被链接到一个 Part 或 ManufacturerPart 对象同一 Part 可以有多个供应商提供见 company/models.py 中 SupplierPart 类注释。权限要求查看、添加、编辑和删除供应商部分同样需要对应的 采购订单用户权限。添加供应商部分创建供应商部分有以下三种入口进入某个 Part 的详情页点击Suppliers侧边标签页进入某个 Supplier 的详情页点击Supplied Parts侧边标签页进入某个 Manufacturer 的详情页点击Supplied Parts侧边标签页。无论从哪个入口进入点击New Supplier Part加号图标按钮打开 Create new Supplier Part 表单填写供应商部分信息后点击Submit提交。编辑供应商部分首先进入供应商部分详情页方式与添加时一致在 Part 详情页的Part Suppliers表格中点击对应链接或在 Supplier / Manufacturer 详情页点击对应Supplier Part链接。加载详情后点击供应商部分图片旁的编辑图标修改信息后点击Submit。禁用供应商部分供应商部分可以被单独禁用disable例如当该供应商部分不再可供采购时。在 InvenTree 系统中禁用后它将不再出现在新采购订单的可选项中但任何已引用它的现有采购订单仍会保持完整不受影响。供应商部分的 active 状态在界面中清晰可见要改变其 active 状态只需编辑该供应商部分详情并将active属性置为否建议推荐使用「禁用」而非「删除」供应商部分这样能保护历史数据的完整性。模型层通过active布尔字段见 SupplierPart 类文档注释实现该开关。删除供应商部分与编辑类似先进入供应商部分详情页然后点击图片旁的红色垃圾桶图标核对要删除的信息、勾选确认复选框后点击Submit。供应商部分可用性AvailabilityInvenTree 支持跟踪供应商部分的「可用性」信息。虽然该信息可以手动更新但结合 InvenTree 插件系统使用时更有价值一个自定义插件可以周期性地通过供应商 API 请求可用性信息并为每个供应商部分更新这些数据。可用性信息一旦提供会显示在供应商部分详情页上。可用性信息也可以直接在用户界面中手动更新在源码中SupplierPart模型定义了availability_updated字段见 company/models.py用于记录可用性数据的最后更新时间这正是插件定期同步可用性信息的落点。供应商部分包装规格Pack Size供应商部分可以定义包装规格pack size在创建或编辑部分时设定默认值为 1。采购时部件是按「包」购买的这一点会在采购订单中被考虑如果包装规格为 5 的供应商部分以数量 4 采购收货时将有 20 个部件加入库存4 × 5 20。手动添加库存时供应商部分可以按「包」或按「单个部件」添加这是为了允许录入已拆包的物品。将 Use pack size 标志API 中为use_pack_size设为 True即可按包添加。从实现上看SupplierPart的base_quantity(quantity)方法见 company/models.py负责将采购数量换算为基础部件数量在 收货流程 中stock_quantity supplier_part.base_quantity(quantity)正是包装规格计算的实际落地逻辑。关于捆绑套件Bundled Items包装规格只表示同一部件的多个单位。如果供应商把多种不同部件打包成一个可购项目套件/组合请参阅 捆绑套件Bundled Items 文档。制造商Manufacturers制造商Manufacturer是一种被标记为外部部件/原材料生产方的 公司 记录。制造商可以是也可以不是这些部件的供应商。权限要求查看、添加、编辑和删除制造商需要相应的 采购订单用户权限。点击Buy导航标签页在下拉列表中选择Manufacturers工厂图标选项即可访问制造商列表。添加制造商在制造商页面点击New Manufacturer按钮打开 Create new Manufacturer 表单填写制造商信息Company name和Company description必填后点击Submit。制造商 vs 供应商如果制造商直接向客户销售可以在提交前勾选is supplier复选框或之后开启。采购订单完全依赖供应商部分supplier parts因此该制造商也必须同时被设置为供应商才能真正参与采购流程。制造商部分Manufacturer Parts制造商部分被链接到一个制造商、被定义为「可生产项目」。添加制造商部分有两种入口进入 Part 详情页点击Suppliers标签页进入 Manufacturer 详情页点击Manufactured Parts标签页。点击New Manufacturer Part按钮打开 Create New Manufacturer Part 表单填写信息后点击Submit。编辑制造商部分进入制造商部分详情页在 Part 详情页的Part Manufacturers表格中点击MPN链接或在 Manufacturer 详情页的Manufactured Parts标签页点击MPN链接点击图片旁的编辑图标修改后提交。删除制造商部分与编辑类似进入详情页点击图片旁的红色垃圾桶图标核对信息、勾选确认复选框后提交。采购订单Purchase Orders采购订单是采购系统的核心。它用于跟踪从供应商和制造商处购买了哪些部件从而将外部购入的物品转换为库存条目stock items / inventory。在数据模型层面PurchaseOrder见 order/models.py拥有以下关键字段字段含义reference订单引用号全局唯一默认由generate_next_purchase_order_reference自动生成status订单状态PENDING / PLACED / ON_HOLD / COMPLETE / CANCELLED 等supplier供货公司仅is_supplierTrue的公司可选supplier_reference供应商侧的订单参考代码target_date期望交付日期超过该日期订单将标记为逾期destination收货目的地库存位置StockLocationresponsible负责管理该订单的用户或组project_code订单关联的项目代码contact/address订单联系人及公司地址查看采购订单从主导航菜单选择Purchasing再从侧边栏选择Purchase Orders即可进入采购订单显示页面有以下两种视图模式表格视图Table View提供采购订单列表可根据用户提供的参数进行过滤仅显示订单子集。日历视图Calendar View基于每个订单指定的各种日期以日历方式展示未完成的采购订单。采购订单状态码每个采购订单都有一个特定的状态码表示订单的当前状态。状态码定义于 order/status_codes.py状态数值含义PENDING10订单待处理尚未下达PLACED20订单已下达给供应商ON_HOLD25订单被挂起COMPLETE30订单已完成CANCELLED40订单已取消LOST50订单丢失RETURNED60订单被退回其中开放订单OPEN组包含 PENDING、ON_HOLD、PLACED失败订单FAILED组包含 CANCELLED、LOST、RETURNED。采购订单状态支持 自定义状态custom states。这些状态转换由 状态机装饰器inventree_transition驱动place_order()允许从 PENDING/ON_HOLD 转到 PLACEDcomplete_order()要求订单处于 PLACEDhold_order()允许从 PENDING/PLACED 转到 ON_HOLDcancel_order()则允许从 PENDING/ON_HOLD/PLACED 取消。每次转换都会触发相应事件如PurchaseOrderEvents.PLACED并通知订阅用户。采购订单货币可以为单个采购订单指定货币代码。如果未指定将使用 供应商 上设置的默认货币此外还可以为每个行项目单独指定货币。因此在确定采购订单中每个行项目的成本时优先级顺序如下行项目货币Line item currency采购订单货币Purchase order currency供应商货币Supplier currency默认基础货币Default / base currency在源码中TotalPriceMixin.currency属性见 order/models.py精确实现了这一优先级链先读order_currency再回退到公司货币最后使用currency_code_default()。而calculate_total_price()见 order/models.py会遍历所有行项目与额外行项目通过convert_money进行汇率换算并按(1 - discount / 100)应用折扣百分比来计算订单总价。创建采购订单在采购订单页面点击New Purchase Order加号图标按钮打开 Create Purchase Order 表单。采购订单必须关联到一个具体的供应商请从现有供应商列表中选择一个。注意只有启用了 Supplier 属性的公司才会显示并可选。填写其余订单信息后点击Submit。采购订单引用号Reference每个采购订单通过其Reference字段唯一标识默认格式为PO-{ref:04d}例如PO-0001。更多信息请阅读 引用字段reference fields。该模式由全局设置PURCHASEORDER_REFERENCE_PATTERN控制见下文设置章节订单保存时会调用rebuild_reference_field自动重建引用号见 order/models.py。添加行项目Line Items在采购订单详情页选择Order Items标签页点击Add Line Item按钮即可将部件链接到采购订单。打开 Add Line Item 表单后从列表中选择一个供应商部分。注意只有来自该采购订单所选供应商的部分才会显示并可选择。这一约束在 模型校验 中强制实现add_line_item()会检查supplier_part.supplier ! self.supplier并抛出ValidationError。自动定价Auto Pricing启用Auto Pricing选项后将根据 供应商部分定价数据 依据行项目数量自动计算Unit Price。启用期间Unit Price字段自动计算、不可手动编辑。该选项默认关闭。折扣Discount每个行项目可以应用可选的 折扣 百分比。上传文件导入行项目可以上传从供应商处导出的采购订单文件而不是手动逐条录入行项目。点击Add Line Item按钮旁的Upload File按钮按照引导步骤操作即可。支持格式此流程仅支持表格数据支持的格式包括CSV、TSV、XLS、XLSX、JSON 和 YAML。额外行项目Extra Line Items行项目 必须引用特定的供应商部分而额外行项目Extra Line Items则可用于任何需要在订单中传达的其他逐项信息——例如运费freight charges或服务费service fees。额外行项目与普通行项目一样支持可选的折扣百分比。在TotalPriceMixin.calculate_total_price()中额外行项目与普通行项目一起参与总价计算见 order/models.py。下达订单Issue Order添加完所有行项目后点击主采购订单详情面板上的发送图标按钮确认订单已提交给供应商。此操作对应模型中的place_order()转换见 order/models.py会将状态从 PENDING/ON_HOLD 推进到 PLACED写入issue_date并通知负责人员及订阅用户。收货Receive Line Items收到订单中的全部物品后采购订单会将行项目转换为库存条目stock items。有两种方式将条目标记为 received逐条标记点击每个行项目上的对勾clipboard-check按钮整体标记点击主采购订单详情面板上的对勾按钮并确认订单中的所有条目均已收到。权限说明将行项目标记为已收货需要 Purchase order 的 ADD 权限。在源码层面receive_line_items()见 order/models.py是收货流程的核心它要求订单状态必须为 PLACED然后为每个已收行项目创建新的StockItem记录写入supplier_part、purchase_order、purchase_price、location、batch等字段并为每条记录生成RECEIVED_AGAINST_PURCHASE_ORDER类型的库存跟踪记录tracking entry同时触发PurchaseOrderEvents.ITEM_RECEIVED事件。值得注意的实现细节包括通过select_for_update()锁定行项目行防止并发收货时的丢失更新lost update若启用了PURCHASEORDER_CONVERT_CURRENCY设置收货时会将采购价换算为基础货币见 order/models.py收货完成后若pending_line_count 0且启用了PURCHASEORDER_AUTO_COMPLETE订单会自动完成见 order/models.py。物品位置Item Location收货时物品的位置必须指定有多种指定方式订单目的地Order Destination采购订单的destination字段可以设置为特定位置。收货时位置将默认使用该目的地位置。行项目位置Line Item Location每个行项目可以设置特定位置。收货时位置将默认使用行项目位置。注意行项目级别指定的目的地会覆盖订单级别指定的目的地。已收物品Received Items每个被标记为 received 的物品都会自动转换为一个库存条目stock item。要查看从该采购订单创建的库存条目列表点击Received Items侧边标签页即可。序列号Serial Numbers如果被收货的部件是 可追溯部件trackable则可以在收货时可选地输入序列号。如果提供则为收到的每个单位创建一个单独的序列化的库存条目。序列号并非接收可追溯部件的必需项——如果留空则为收到的数量创建一个非序列化的库存条目。例如在按 外部制造订单 接收一批单位、且该批单位将在制造流程后期 序列化 的场景下这种处理方式非常有用。源码中receive_line_items()通过serials参数区分两种模式提供序列号时调用StockItem._create_serial_numbers()逐个创建否则创建一个聚合库存条目见 order/models.py。物品价值货币Item Value Currency采购订单行项目的单位成本会传递到所创建的库存条目。默认情况下库存条目使用与采购订单行项目相同的货币。但是如果启用了 Convert Currency 设置则库存条目的货币将在收货时转换为系统的 默认货币。当以不同货币订购库存时这一设置非常有用可确保库存条目的单位成本在收货时换算为基础货币。捆绑套件Bundled Items有些供应商只以单个捆绑或套件kit产品出售一组组件而不是作为单独的采购行项目——例如包含各种不同螺丝的紧固件套件或包含某个用途所需多个组件的入门套件。InvenTree 允许将捆绑套件建模为装配体assembly以便在需要时拆分为各个组件而不是将捆绑物作为单个不透明的库存数量接收创建一个代表捆绑物本身的部件并将其标记为 装配件assembly将一个 供应商部分 链接到该捆绑物部件代表它从供应商处如何采购为捆绑物部件定义 物料清单Bill of Materials列出每个单独组件及单个捆绑物中所含的数量照常针对捆绑物的供应商部分创建并接收采购订单——将为捆绑物创建一个库存条目保留整个订单的采购价和来源采购订单信息。当真正需要这些单独组件时可以将已收的捆绑物库存条目 拆解disassemble 为其组件部分。原始捆绑物的采购价格和可追溯性数据批次代码、来源采购订单会自动分摊到新生成的组件库存条目上。包装规格 vs 捆绑套件包装规格大于 1 的供应商部分仍然代表同一部件的多个单位——包装规格仅决定每订购一个单位会向库存添加多少个物理单位。而捆绑套件则不同一个供应商部分代表不同组件的集合必须先拆解各组件才能单独使用或销售。完成订单Complete Order一旦所有已收货条目的数量等于或大于所有行项目的数量订单将自动标记为complete完成。也可以在全部物品到货之前完成订单或存在缺货时。为此点击主采购订单详情面板上的绿色对勾circle-check按钮确认订单已完成。对应源码中的complete_order()转换见 order/models.py会写入complete_date并触发已完成部件的定价刷新。取消订单Cancel Order如果订单将不再处理用户可以选择取消订单。只需点击主采购订单详情面板上的红色圆形叉circle-x按钮确认该采购订单已被取消。源码中的cancel_order()见 order/models.py仅允许取消开放状态的订单并会通知负责人员。复制采购订单Duplicate Purchase Order复制采购订单允许用户快速创建现有订单的新副本复用相同的供应商和行项目信息。要复制现有订单请从屏幕右上角的菜单中选择Duplicate Order操作这会打开一个对话框你可以在此调整新订单的参数后再实际创建。表单中提供了一些额外选项用于控制单个行项目的复制随后将基于当前所选订单创建一个新的采购订单订单排程Order Scheduling采购订单可以排程到未来日期以便规划未来的订单。开始日期Start Date计划向供应商下达订单的日期目标日期Target Date预计从供应商完成/收到订单的日期逾期订单Overdue Orders如果到了Target Date订单仍未完成订单将被标记为overdue逾期。源码中 overdue_filter() 实现了逾期判定逻辑状态属于 OPEN 组、存在target_date且target_date早于今天。模型字段target_date的 help_text 也明确写着 Order will be overdue after this date见 order/models.py。日历视图与 ICS 导出使用采购订单列表右上角的日历按钮视图可以切换到日历视图。此视图仅显示定义了目标日期的订单。该视图还可以作为 ICS 日历被外部访问URL 形如http://inventree.example.org/api/order/calendar/purchase-order/calendar.ics默认情况下已完成的订单不会被导出。可以通过在 URL 后追加?include_completedTrue将其包含在内。采购订单设置以下是可用的采购订单 全局设置其默认值与描述定义于 common/setting/system.py设置键说明默认值PURCHASEORDER_ENABLED在用户界面中启用采购订单功能TruePURCHASEORDER_REFERENCE_PATTERN生成采购订单引用号的必需模式PO-{ref:04d}PURCHASEORDER_REQUIRE_RESPONSIBLE每个订单必须指定负责的所有者用户或组FalsePURCHASEORDER_CONVERT_CURRENCY收货时将物品价值换算为基础货币FalsePURCHASEORDER_EDIT_COMPLETED_ORDERS允许编辑已完成/已发货后的采购订单FalsePURCHASEORDER_AUTO_COMPLETE当所有行项目都收货后自动将采购订单标记为完成TruePURCHASEORDER_MERGE_LINE_ITEMS将新的采购订单行项目与共享相同部件、目的地和目标日期的现有行合并True各设置的实际作用可以在源码中找到对应证据PURCHASEORDER_REQUIRE_RESPONSIBLE在Order.clean()中强制校验responsible字段见 order/models.pyPURCHASEORDER_EDIT_COMPLETED_ORDERS作为UNLOCK_SETTING控制已完成订单是否可被编辑——当设置为False时完成后的订单会被锁定见 order/models.pyPURCHASEORDER_CONVERT_CURRENCY在receive_line_items()中决定是否调用convert_money()换算收货价见 order/models.py相关行为由 order/tests.py 的测试用例验证PURCHASEORDER_AUTO_COMPLETE在收货循环结束时判断是否自动完成订单见 order/models.pyPURCHASEORDER_MERGE_LINE_ITEMS控制是否将相同供应商部分的新行项目合并到既有行中在 order/api.py 与 order/serializers.py 中被读取并有对应测试覆盖见 order/test_api.py。采购全流程速览综合以上内容一次完整的 InvenTree 采购操作可归纳为以下步骤建立供应商/制造商创建公司记录并启用is supplier如需直销还可启用is manufacturer定义供应商部分为每个可采购部件创建 Supplier Part关联 SKU、包装规格、定价创建采购订单选择供应商生成唯一 Reference添加行项目可开启自动定价或上传文件批量导入下达订单点击发送按钮将状态推进至 PLACED收货入库逐条或批量标记已收指定收货位置、批次与序列号可追溯部件系统自动生成库存条目与跟踪记录完成/取消/复制/排程根据实际业务流转订单状态或复制历史订单复用行项目亦可为目标日期设置排程跟踪逾期。整个流程的状态机、货币换算、包装规格换算与自动完成逻辑均可在 order/models.py、order/status_codes.py 及 company/models.py 中找到对应实现配合 order/test_api.py 与 order/tests.py 中的测试用例可作为深入学习与二次开发的起点。【免费下载链接】InvenTreeOpen Source Inventory Management System项目地址: https://gitcode.com/GitHub_Trending/in/InvenTree创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考