# 店长工资计算规则 - 完整逻辑梳理 ## 📋 概述 店长工资由以下几个部分组成: 1. **底薪**:固定4000元,根据考核指标扣款 2. **提成**:根据门店分类和业绩是否达标,使用不同的提成比例计算(基于毛利) --- ## 💰 工资组成规则 ### 1. 底薪规则 **固定底薪**:4000元 #### 老店店长底薪考核 **考核指标**(3个): 1. **业绩考核**:门店业绩是否达到门店生命线 2. **人头考核**:进店消耗人数是否达到目标人头数 3. **消耗考核**:门店消耗是否达到目标消耗 **扣款规则**: - 每个指标未达到:扣除500元 - 如果3个指标都未达到:扣除1500元(500 × 3) **计算公式**: ``` 底薪 = 4000 - (未达标指标数 × 500) ``` #### 新店店长底薪考核 **重要说明**:新店店长涉及全部阶段,都有负奖励机制 **考核指标**(2个): 1. **业绩考核**:门店业绩是否达到门店生命线 2. **人头考核**:进店消耗人数是否达到目标人头数 **扣款规则**: - 每个指标未达到:扣除800元 - 如果2个指标都未达到:扣除1600元(800 × 2) **计算公式**: ``` 底薪 = 4000 - (未达标指标数 × 800) ``` **注意**:新店不考核消耗指标 **旗舰店特殊规则**: - 旗舰店类型门店需要扣除负奖励800元 - 判断方式:`lq_mdxx.F_StoreType = 2`(StoreTypeEnum.旗舰店) --- ### 2. 提成规则 **提成计算方式**:根据门店分类和业绩是否达标,使用不同的提成比例 **重要说明**:提成计算基于**毛利**,不是门店业绩 #### 老店店长提成规则 根据门店分类(A、B、C类)和业绩是否达标,使用不同的提成比例: | 门店分类 | 业绩未达标 | 业绩达标 | |---------|----------|---------| | A类门店 | 3% | 3.5% | | B类门店 | 3.5% | 4% | | C类门店 | 4% | 4.5% | **业绩达标判断**: - 业绩达标:门店业绩 ≥ 门店生命线 - 业绩未达标:门店业绩 < 门店生命线 **计算公式**: ``` 如果 业绩 ≥ 生命线(业绩达标): 提成 = 毛利 × 对应提成比例(业绩达标) 如果 业绩 < 生命线(业绩未达标): 提成 = 毛利 × 对应提成比例(业绩未达标) ``` #### 新店店长提成规则 **提成比例**(不区分门店分类): - 业绩未达标:3% - 业绩达标:3.5% **计算公式**: ``` 如果 业绩 ≥ 生命线(业绩达标): 提成 = 毛利 × 3.5% 如果 业绩 < 生命线(业绩未达标): 提成 = 毛利 × 3% ``` --- ## 📊 毛利计算公式 **核心公式**: ``` 毛利 = 销售业绩 - 产品物料 - 合作项目成本 - 店内支出 - 洗毛巾 ``` ### 1. 销售业绩 **计算公式**: ``` 销售业绩 = 开单业绩 - 退款业绩 ``` **数据来源**: 1. **开单业绩**: - 表:`lq_kd_kdjlb`(开单记录表) - 字段:`sfyj`(实付业绩) - 条件: - `F_IsEffective = 1`(有效记录) - `Djmd = @StoreId`(门店ID) - `DATE_FORMAT(Kdrq, '%Y%m') = @Month`(月份,YYYYMM格式) 2. **退款业绩**: - 表:`lq_hytk_hytk`(退卡记录表) - 字段:`F_ActualRefundAmount`(实际退款金额) - 条件: - `F_IsEffective = 1`(有效记录) - `md = @StoreId`(门店ID) - `DATE_FORMAT(tksj, '%Y%m') = @Month`(月份,YYYYMM格式) **SQL示例**: ```sql -- 开单业绩 SELECT COALESCE(SUM(sfyj), 0) as BillingPerformance FROM lq_kd_kdjlb WHERE Djmd = @StoreId AND DATE_FORMAT(Kdrq, '%Y%m') = @Month AND F_IsEffective = 1 -- 退款业绩 SELECT COALESCE(SUM(F_ActualRefundAmount), 0) as RefundPerformance FROM lq_hytk_hytk WHERE md = @StoreId AND DATE_FORMAT(tksj, '%Y%m') = @Month AND F_IsEffective = 1 -- 销售业绩 销售业绩 = 开单业绩 - 退款业绩 ``` --- ### 2. 产品物料 **计算公式**: ``` 产品物料 = 仓库领用金额合计 ``` **数据来源**: - 表:`lq_inventory_usage`(库存使用记录表) - 字段:`F_TotalAmount`(合计金额) - 条件: - `F_IsEffective = 1`(有效记录) - `F_StoreId = @StoreId`(门店ID) - **特殊规则**:核算11月工资时,算的是10月份的仓库领用 - 如果计算月份是11月,则查询10月的数据 - 其他月份正常查询当月数据 **SQL示例**: ```sql -- 产品物料(特殊规则:11月工资算10月数据) SET @QueryMonth = @Month; IF @Month = '202411' THEN SET @QueryMonth = '202410'; END IF; SELECT COALESCE(SUM(F_TotalAmount), 0) as MaterialCost FROM lq_inventory_usage WHERE F_StoreId = @StoreId AND DATE_FORMAT(F_UsageTime, '%Y%m') = @QueryMonth AND F_IsEffective = 1 ``` --- ### 3. 合作项目成本 **计算公式**: ``` 合作项目成本 = 合作成本表合计金额 ``` **数据来源**: - 表:`lq_cooperation_cost`(合作成本表)**需要新建** - 字段:`F_TotalAmount`(合计金额) - 条件: - `F_StoreId = @StoreId`(门店ID) - `F_Year = @Year`(年份) - `F_Month = @Month`(月份,YYYYMM格式) **表结构设计**: ```sql CREATE TABLE IF NOT EXISTS `lq_cooperation_cost` ( `F_Id` VARCHAR(50) NOT NULL COMMENT '主键ID', `F_StoreId` VARCHAR(50) NOT NULL COMMENT '门店ID(关联lq_mdxx.F_Id)', `F_StoreName` VARCHAR(200) NULL COMMENT '门店名称', `F_Year` INT NOT NULL COMMENT '年份', `F_Month` VARCHAR(6) NOT NULL COMMENT '月份(YYYYMM格式)', `F_TotalAmount` DECIMAL(18,2) DEFAULT 0.00 COMMENT '合计金额', `F_Remarks` VARCHAR(1000) NULL COMMENT '备注说明', `F_IsEffective` INT DEFAULT 1 COMMENT '是否有效(1:有效 0:无效)', `F_CreateUser` VARCHAR(50) NULL COMMENT '创建人ID', `F_CreateTime` DATETIME NULL COMMENT '创建时间', `F_UpdateUser` VARCHAR(50) NULL COMMENT '更新人ID', `F_UpdateTime` DATETIME NULL COMMENT '更新时间', PRIMARY KEY (`F_Id`), KEY `idx_store_month` (`F_StoreId`, `F_Year`, `F_Month`), KEY `idx_month` (`F_Year`, `F_Month`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='合作成本表'; ``` **功能要求**: - 支持按门店、年份、月份查询 - 支持导入功能(Excel导入) - 支持增删改查操作 --- ### 4. 店内支出 **计算公式**: ``` 店内支出 = 店内支出表合计金额 ``` **数据来源**: - 表:`lq_store_expense`(店内支出表)**需要新建** - 字段:`F_Amount`(金额) - 条件: - `F_StoreId = @StoreId`(门店ID) - `DATE_FORMAT(F_ExpenseDate, '%Y%m') = @Month`(月份,YYYYMM格式) - `F_IsEffective = 1`(有效记录) **业务流程**: 1. 从报销表导出本月审核通过的报销表明细 - 表:`lq_reimbursement_application`(报销申请表) - 关联表:`lq_purchase_records`(购买记录表) - 条件: - `F_ApprovalStatus = '已通过'`(审批状态) - `F_ApplicationStoreId = @StoreId`(门店ID) - `DATE_FORMAT(F_ApplicationTime, '%Y%m') = @Month`(月份) 2. 线下重新整理明细(可能调整金额、分类等) 3. 导入到店内支出表 `lq_store_expense` **表结构设计**(参考购买记录表结构): ```sql CREATE TABLE IF NOT EXISTS `lq_store_expense` ( `F_Id` VARCHAR(50) NOT NULL COMMENT '主键ID', `F_StoreId` VARCHAR(50) NOT NULL COMMENT '门店ID(关联lq_mdxx.F_Id)', `F_StoreName` VARCHAR(200) NULL COMMENT '门店名称', `F_ExpenseCategoryId` VARCHAR(50) NULL COMMENT '支出分类ID(关联lq_reimbursement_category.F_Id)', `F_ExpenseCategoryName` VARCHAR(200) NULL COMMENT '支出分类名称', `F_ExpenseDate` DATETIME NOT NULL COMMENT '支出日期', `F_UnitPrice` DECIMAL(18,2) DEFAULT 0.00 COMMENT '单价', `F_Quantity` INT DEFAULT 0 COMMENT '数量', `F_Amount` DECIMAL(18,2) DEFAULT 0.00 COMMENT '金额', `F_Memo` VARCHAR(1000) NULL COMMENT '备注说明', `F_Attachment` TEXT NULL COMMENT '附件(JSON格式)', `F_RelatedReimbursementId` VARCHAR(50) NULL COMMENT '关联报销申请ID(可选)', `F_RelatedPurchaseRecordId` VARCHAR(50) NULL COMMENT '关联购买记录ID(可选)', `F_IsEffective` INT DEFAULT 1 COMMENT '是否有效(1:有效 0:无效)', `F_CreateUser` VARCHAR(50) NULL COMMENT '创建人ID', `F_CreateTime` DATETIME NULL COMMENT '创建时间', `F_UpdateUser` VARCHAR(50) NULL COMMENT '更新人ID', `F_UpdateTime` DATETIME NULL COMMENT '更新时间', PRIMARY KEY (`F_Id`), KEY `idx_store_date` (`F_StoreId`, `F_ExpenseDate`), KEY `idx_expense_date` (`F_ExpenseDate`), KEY `idx_category` (`F_ExpenseCategoryId`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='店内支出表'; ``` **功能要求**: - 支持按门店、月份查询 - 支持导出报销表明细(用于线下整理) - 支持导入功能(Excel导入) - 支持增删改查操作 --- ### 5. 洗毛巾 **计算公式**: ``` 洗毛巾 = 送洗记录总费用 ``` **数据来源**: - 表:`lq_laundry_flow`(清洗流水表) - 字段:`F_TotalPrice`(总费用) - 条件: - `F_FlowType = 0`(流水类型:送出) - `F_StoreId = @StoreId`(门店ID) - `DATE_FORMAT(F_CreateTime, '%Y%m') = @Month`(月份,YYYYMM格式) - `F_IsEffective = 1`(有效记录) **重要说明**: - 只要送出就产生金额(不管是否送回) - 只统计 `F_FlowType = 0`(送出)的记录 **SQL示例**: ```sql SELECT COALESCE(SUM(F_TotalPrice), 0) as LaundryCost FROM lq_laundry_flow WHERE F_StoreId = @StoreId AND F_FlowType = 0 AND DATE_FORMAT(F_CreateTime, '%Y%m') = @Month AND F_IsEffective = 1 ``` --- ## 🔍 其他重要规则 ### 1. 旗舰店判断 **判断方式**: - 表:`lq_mdxx`(门店信息表) - 字段:`F_StoreType`(门店类型) - 枚举值: - `1` = 门店200平(StoreTypeEnum.门店200平) - `2` = 旗舰店(StoreTypeEnum.旗舰店) **代码实现**: ```csharp // 判断是否为旗舰店 bool isFlagshipStore = store.StoreType == (int)StoreTypeEnum.旗舰店; ``` **特殊规则**: - 旗舰店类型门店需要扣除负奖励800元 --- ### 2. 新店店长 **重要说明**: - 新店店长所有阶段都有负奖励 - 新店判断逻辑:需要根据门店开业时间或新店保护期判断(参考其他工资计算服务) --- ### 3. 店长岗位名称 **系统标识**: - 岗位名称:`"店长"` - 查询条件:`BASE_USER.F_ZW = "店长"` 或 `BASE_USER.F_GW = "店长"` --- ## 📋 数据来源总结 ### 核心数据表 1. **门店信息表** (`lq_mdxx`) - `F_Id`:门店ID - `F_StoreType`:门店类型(判断旗舰店) - `F_StoreCategory`:门店分类(A、B、C类) 2. **门店目标表** (`lq_md_target`) - `F_StoreId`:门店ID - `F_Month`:月份(YYYYMM格式) - `F_StoreLifeline`:门店生命线 - `F_HeadcountTarget`:目标人头数 - `F_ConsumeTarget`:目标消耗 3. **开单记录表** (`lq_kd_kdjlb`) - `sfyj`:实付业绩(开单业绩) - `Djmd`:门店ID - `Kdrq`:开单日期 4. **退卡记录表** (`lq_hytk_hytk`) - `F_ActualRefundAmount`:实际退款金额(退款业绩) - `md`:门店ID - `tksj`:退卡时间 5. **库存使用记录表** (`lq_inventory_usage`) - `F_TotalAmount`:合计金额(产品物料) - `F_StoreId`:门店ID - `F_UsageTime`:使用时间 6. **合作成本表** (`lq_cooperation_cost`) **需要新建** - `F_TotalAmount`:合计金额 - `F_StoreId`:门店ID - `F_Year`:年份 - `F_Month`:月份 7. **店内支出表** (`lq_store_expense`) **需要新建** - `F_Amount`:金额 - `F_StoreId`:门店ID - `F_ExpenseDate`:支出日期 8. **清洗流水表** (`lq_laundry_flow`) - `F_TotalPrice`:总费用(洗毛巾) - `F_StoreId`:门店ID - `F_FlowType`:流水类型(0=送出) 9. **耗卡记录表** (`lq_xh_hyhk`) - 用于统计进店消耗人数 10. **系统用户表** (`BASE_USER`) - `F_REALNAME`:姓名 - `F_ZW`:职位(店长) - `F_MDID`:门店ID --- ## 🚀 需要先实现的功能 ### 第一阶段:基础数据表 #### 1. 合作成本表 (`lq_cooperation_cost`) **功能清单**: - [ ] 创建表结构(SQL) - [ ] 创建实体类 (`LqCooperationCostEntity`) - [ ] 创建DTO类(输入/输出) - [ ] 创建Service类 (`LqCooperationCostService`) - [ ] 实现CRUD接口 - [ ] 实现导入功能(Excel导入) - [ ] 实现查询接口(按门店、年份、月份) **优先级**:高(毛利计算必需) --- #### 2. 店内支出表 (`lq_store_expense`) **功能清单**: - [ ] 创建表结构(SQL) - [ ] 创建实体类 (`LqStoreExpenseEntity`) - [ ] 创建DTO类(输入/输出) - [ ] 创建Service类 (`LqStoreExpenseService`) - [ ] 实现CRUD接口 - [ ] 实现导出功能(导出报销表明细) - [ ] 实现导入功能(Excel导入) - [ ] 实现查询接口(按门店、月份) **优先级**:高(毛利计算必需) --- ### 第二阶段:数据查询接口 #### 3. 毛利计算接口 **功能清单**: - [ ] 实现销售业绩查询(开单业绩 - 退款业绩) - [ ] 实现产品物料查询(仓库领用金额,特殊规则:11月算10月) - [ ] 实现合作项目成本查询 - [ ] 实现店内支出查询 - [ ] 实现洗毛巾查询 - [ ] 实现毛利汇总计算接口 **优先级**:高(工资计算必需) --- ### 第三阶段:工资计算 #### 4. 店长工资计算服务 **功能清单**: - [ ] 实现底薪计算(老店/新店,旗舰店特殊规则) - [ ] 实现提成计算(基于毛利,老店/新店不同规则) - [ ] 实现考核指标判断(业绩、人头、消耗) - [ ] 实现新店判断逻辑 - [ ] 实现旗舰店判断逻辑 - [ ] 实现完整工资计算接口 **优先级**:中(依赖第一阶段和第二阶段) --- ## 📝 实现顺序建议 ### 步骤1:创建合作成本表 1. 编写SQL创建表结构 2. 创建实体类、DTO、Service 3. 实现CRUD接口 4. 实现导入功能 ### 步骤2:创建店内支出表 1. 编写SQL创建表结构 2. 创建实体类、DTO、Service 3. 实现CRUD接口 4. 实现导出报销表明细功能 5. 实现导入功能 ### 步骤3:实现毛利计算接口 1. 实现销售业绩查询 2. 实现产品物料查询(注意11月特殊规则) 3. 实现合作项目成本查询 4. 实现店内支出查询 5. 实现洗毛巾查询 6. 实现毛利汇总计算 ### 步骤4:实现店长工资计算 1. 实现底薪计算逻辑 2. 实现提成计算逻辑 3. 实现考核指标判断 4. 实现完整工资计算接口 5. 编写测试用例验证 --- ## ⚠️ 注意事项 1. **产品物料特殊规则**: - 核算11月工资时,算的是10月份的仓库领用 - 需要在查询时特殊处理 2. **店内支出流程**: - 必须先导出报销表明细 - 线下整理后再导入 - 不是直接从报销表计算 3. **洗毛巾计算**: - 只要送出就产生金额 - 只统计 `F_FlowType = 0`(送出)的记录 4. **旗舰店判断**: - 使用 `F_StoreType = 2` 判断 - 需要扣除负奖励800元 5. **新店店长**: - 所有阶段都有负奖励 - 需要确认新店判断逻辑 6. **数据一致性**: - 所有金额计算保留2位小数 - 确保月份格式统一(YYYYMM) --- ## 📌 待确认问题 1. **新店判断逻辑**: - 如何判断门店是否为新店? - 是否有新店保护期字段? - 参考其他工资计算服务的实现 2. **合作成本导入格式**: - Excel导入的字段格式要求 - 是否需要校验门店ID、年份、月份 3. **店内支出导入格式**: - Excel导入的字段格式要求 - 是否需要关联报销申请ID 4. **毛利计算精度**: - 各组成部分的精度要求 - 最终毛利的精度要求 --- ## 🔗 相关代码位置 - **门店信息查询**:`LqMdxxService.cs` - **门店分类枚举**:`StoreCategoryEnum.cs` - **门店类型枚举**:`StoreTypeEnum.cs` - **门店实体类**:`LqMdxxEntity.cs` - **库存使用服务**:`LqInventoryUsageService.cs` - **清洗流水服务**:`LqLaundryFlowService.cs` - **报销申请服务**:`LqReimbursementApplicationService.cs` - **购买记录服务**:`LqPurchaseRecordsService.cs` - **其他工资计算服务**:`LqAssistantSalaryService.cs`、`LqDirectorSalaryService.cs`(参考新店判断逻辑)