客户发票
交易 被组合在一起形成发票,发票会发送给客户以便付款。
发票有一个开始和结束日期,这表示发票覆盖的期间,以及到期日,这是发票到期付款的日期。

发票可以由系统自动生成,例如,当服务被计费时,会为零售成本创建发票,或者它们可以手动创建,例如,如果客户请求发票副本,或者如果客户被计费一次性费用。
客户发票完全使用 Mailjet 模板化,并可以自定义以包含公司徽标、地址和付款详情,并可以通过电子邮件发送给客户,或下载为 PDF。

自定义发票模板
OmniCRM 使用 HTML 模板和 Jinja2 模板生成发票。您可以完全自定义发票设计、品牌、颜色和布局。
发票模板位置
发票模板存储在 OmniCRM-API/invoice_templates/
默认模板:
norfone_invoice_template.html- 示例发票模板cifi_invoice_template.html- 替代模板示例
配置:
活动发票模板在 OmniCRM-API/crm_config.yaml 中指定:
invoice:
template_filename: 'norfone_invoice_template.html'
可用模板变量
发票模板可以访问以下 Jinja2 变量:
发票信息:
{{ invoice_number }}- 唯一发票 ID(例如,INV-2025-001234){{ date }}- 发票发行日期(ISO 格式:2025-01-10T12:00:00){{ due_date }}- 付款到期日(例如,2025-02-10){{ start_date }}- 计费期间开始日期{{ end_date }}- 计费期间结束日期{{ total_amount }}- 税前总发票金额(数值){{ total_tax }}- 从所有交易计算的总税额(数值)
客户信息:
{{ client.name }}- 客户的全名或公司名称{{ client.address.address_line_1 }}- 地址行 1{{ client.address.address_line_2 }}- 地址行 2{{ client.address.city }}- 城市{{ client.address.state }}- 州/省{{ client.address.zip_code }}- 邮政编码{{ client.address.country }}- 国家
交易行项目:
使用以下代码循环遍历交易:
{% for sub_transaction in transactions %}
<tr>
<td>{{ sub_transaction.transaction_id }}</td>
<td>{{ sub_transaction.created.split("T")[0] }}</td>
<td>{{ sub_transaction.title }}</td>
<td>{{ sub_transaction.description }}</td>
<td>${{ "%.2f"|format(sub_transaction.retail_cost) }}</td>
</tr>
{% endfor %}
交易字段:
sub_transaction.transaction_id- 交易 IDsub_transaction.created- 交易日期/时间sub_transaction.title- 交易标题sub_transaction.description- 详细描述sub_transaction.retail_cost- 行项目金额sub_transaction.tax_percentage- 应用的税率(例如,10 表示 10%)sub_transaction.tax_amount- 以美元计算的税额
在模板中显示税:
<td>
{% if sub_transaction.tax_amount and sub_transaction.tax_amount > 0 %}
${{ "%.2f"|format(sub_transaction.tax_amount) }} ({{ sub_transaction.tax_percentage }}%)
{% else %}
-
{% endif %}
</td>
创建自定义发票模板
步骤 1:复制现有模板
cd OmniCRM-API/invoice_templates/
cp norfone_invoice_template.html your_company_invoice_template.html
步骤 2:自定义 HTML/CSS
编辑 your_company_invoice_template.html 以匹配您的品牌:
关键自定义区域:
-
公司徽标和品牌
<!-- 替换为您的徽标 URL -->
<img src="https://yourcompany.com/logo.png" alt="您的公司" width="200">
<!-- 更新公司名称 -->
<h1>您的公司名称</h1> -
配色方案
<style>
/* 主要品牌颜色 */
.navbar {
background: linear-gradient(to bottom right, #your-color-1, #your-color-2);
}
/* 表头 */
.table thead th {
background-color: #your-brand-color !important;
color: white !important;
}
/* 按钮和链接 */
.btn-primary {
background-color: #your-brand-color;
}
</style> -
公司信息页脚
<footer>
<p>您的公司名称</p>
<p>123 商业街,城市,国家</p>
<p>电话: +1-555-123-4567 | 邮箱: billing@yourcompany.com</p>
<p>ABN/税号: 12345678900</p>
</footer> -
付款说明
<div class="payment-info">
<h3>付款方式</h3>
<p><strong>在线:</strong> 在 https://yourcompany.com/pay 付款</p>
<p><strong>银行转账:</strong></p>
<ul>
<li>账户名称:您的公司有限公司</li>
<li>BSB:123-456</li>
<li>账户号码:987654321</li>
<li>参考:{{ invoice_number }}</li>
</ul>
</div> -
条款和条件
<div class="terms">
<h4>付款条款</h4>
<p>发票日期后 30 天内到期付款。</p>
<p>逾期付款费用:逾期余额每月 2%。</p>
<p>有关账单查询:billing@yourcompany.com</p>
</div>
步骤 3:更新配置
编辑 OmniCRM-API/crm_config.yaml:
invoice:
template_filename: 'your_company_invoice_template.html'
步骤 4:重启 API
cd OmniCRM-API
sudo systemctl restart omnicrm-api
步骤 5:测试发票生成
- 导航到有交易的客户
- 生成测试发票
- 下载 PDF 以验证格式
- 将发票通过电子邮件发送给自己以测试电子邮件发送
高级自定义
条件内容:
使用 Jinja2 条件显示/隐藏内容:
{% if total_amount > 1000 %}
<div class="high-value-notice">
<p><strong>注意:</strong> 大额余额 - 可根据请求提供付款计划。</p>
</div>
{% endif %}
{% if client.address.country == "Australia" %}
<p>包含 GST: ${{ "%.2f"|format(total_amount * 0.10) }}</p>
{% endif %}
多语言支持:
创建特定语言的模板:
invoice_template_en.html
invoice_template_es.html
invoice_template_fr.html
根据客户的语言偏好进行配置。
自定义计算:
<!-- 显示小计和税务明细 -->
<tr>
<td colspan="4" class="text-right"><strong>小计:</strong></td>
<td>${{ "%.2f"|format(total_amount) }}</td>
</tr>
<tr>
<td colspan="4" class="text-right"><strong>税:</strong></td>
<td>${{ "%.2f"|format(total_tax) }}</td>
</tr>
<tr>
<td colspan="4" class="text-right"><strong>总计:</strong></td>
<td>${{ "%.2f"|format(total_amount + total_tax) }}</td>
</tr>
注意: total_tax 变量是通过对发票中所有交易的 tax_amount 进行求和自动计算的。每个交易的税是根据其 tax_percentage 字段计算的,如果未指定,则默认为产品的 tax_percentage 或 0%。
付款的二维码:
生成用于移动支付的二维码:
<div class="qr-payment">
<img src="https://api.qrserver.com/v1/create-qr-code/?size=150x150&data={{ payment_url }}"
alt="扫描付款">
<p>用您的手机扫描以立即付款</p>
</div>
PDF 样式最佳实践
OmniCRM 使用 WeasyPrint 将 HTML 转换为 PDF。请遵循以下指南:
支持的 CSS:
- 大多数 CSS 2.1 属性
- 有限的 CSS3(flexbox,一些变换)
- 通过
@font-face使用网页字体
不支持:
- JavaScript
- CSS 网格(请使用表格)
- 复杂动画
- 一些现代 CSS 属性
页面大小和边距:
@page {
size: A4;
margin: 1cm;
}
body {
font-family: Arial, sans-serif;
font-size: 10pt;
}
打印特定样式:
@media print {
.no-print {
display: none;
}
.page-break {
page-break-after: always;
}
}
表格布局:
.table {
table-layout: fixed;
width: 100%;
}
.table th, .table td {
word-wrap: break-word;
padding: 4px;
}
字体嵌入:
对于自定义字体,使用网页安全字体或嵌入:
@font-face {
font-family: 'YourFont';
src: url('https://yourcompany.com/fonts/yourfont.woff2') format('woff2');
}
body {
font-family: 'YourFont', Arial, sans-serif;
}
测试发票模板
测试清单:
- 视觉检查:
- 徽标正确显示
- 颜色符合品牌指南
- 文本可读(不太小)
- 表格正确对齐
- 所有部分均存在
- 数据准确性:
- 客户详细信息正确
- 交易金额正确相加
- 日期格式正确
- 所有变量正确替换
- PDF 质量:
- 文件大小合理(<5MB)
- 图像清晰锐利
- 无文本截断或溢出
- 页面在适当位置换行
- 多页发票:
- 页眉在每页重复
- 页码显示
- 长交易列表正确分页
- 电子邮件发送:
- PDF 附加到电子邮件
- 文件大小低于 Mailjet 限制(15MB)
- 在 Gmail、Outlook、Apple Mail 中呈现
测试命令(手动生成):
您可以通过 API 测试发票生成:
curl -X GET "http://localhost:5000/crm/invoice/{invoice_id}/pdf" \
-H "Authorization: Bearer YOUR_TOKEN" \
--output test_invoice.pdf
常见模板问题
变量未替换:
- 原因: 变量名称拼写错误或缺少数据
- 修复: 检查拼写是否完全正确(区分大小写),验证数据库中是否存在数据
PDF 样式破损:
- 原因: 不支持的 CSS 属性
- 修复: 使用 CSS 2.1 属性,测试 WeasyPrint 兼容的 CSS
图像未显示:
- 原因: 相对 URL 或被阻止的外部资源
- 修复: 使用绝对 HTTPS URL,确保图像公开可访问
表格溢出页面:
- 原因: 固定列宽度过宽
- 修复: 使用百分比宽度,
table-layout: fixed
字体未呈现:
- 原因: 字体未嵌入或不可用
- 修复: 使用网页安全字体(Arial、Times New Roman 等)或正确嵌入自定义字体
PDF 生成失败:
- 原因: HTML 语法错误或 WeasyPrint 崩溃
- 修复: 验证 HTML,检查 WeasyPrint 日志,简化复杂布局
发票 PDF 缓存
为了提高性能并减少冗余的 PDF 生成,OmniCRM 包括一个发票 PDF 缓存系统。当首次生成发票 PDF 时,它会被缓存到数据库中以供后续请求使用。
PDF 缓存工作原理:
- 首次请求 - 当请求发票 PDF(下载或电子邮件)时,系统:
- 从发票模板生成 PDF
- 将 PDF 编码为 Base64
- 计算 PDF 内容的 SHA256 哈希
- 存储在
Invoice_PDF_Cache表中,包含:- 发票 ID 引用
- PDF 数据(Base64 编码)
- 文件名
- 内容哈希(用于完整性验证)
- 创建时间戳
- 后续请求 - 当再次请求相同发票时:
- 系统通过 invoice_id 检查缓存的 PDF
- 如果缓存存在且有效,则立即返回缓存的 PDF
- 更新
last_accessed时间戳以跟踪缓存使用情况
- 缓存失效 - 当以下情况发生时,缓存的 PDF 会失效:
- 发票被修改(添加/删除交���,详情更改)
- 发票模板被更新
- 手动触发缓存清除
好处:
- 性能 - 对于重复请求,立即提供 PDF(无再生延迟)
- 一致性 - 所有下载的发票都为相同 PDF(除非发票被修改)
- 服务器负载 - 减少 PDF 生成的 CPU 使用
- 用户体验 - 在初始生成期间出现加载指示器,后续请求立即响应
缓存管理:
发票 PDF 缓存由系统自动管理。可以根据以下条件定期清除旧的或未使用的缓存条目:
- 年龄(例如,删除超过 90 天的缓存条目)
- 访问模式(删除 30 天未访问的条目)
- 存储限制(如有需要,实施缓存大小限制)
API 行为:
通过 API 或 UI 下载发票时:
- 首次请求:在生成 PDF 时显示加载指示器,然后缓存
- 后续请求:从缓存中立即下载
- 缓存命中/未命中对用户是透明的
重要: 当您更新发票模板时,请清除缓存以确保新发票使用更新的设计:
-- 清除所有缓存的发票 PDF(在 MySQL 中运行)
DELETE FROM Invoice_PDF_Cache;
或更新 crm_config.yaml 以在模板更改时自动使缓存失效。
访问发票
可以在系统级别或按客户查看发票:
按客户查看:
- 导航到 客户 → [选择客户]
- 点击 账单 标签
- 在第三个卡片中查看发票列表
系统范围查看:
- 导航到 账单 → 发票(从主菜单)
- 查看所有客户的所有发票
发票统计小部件
在发票页面顶部,四个统计卡片显示财务摘要。
{.align-center width="800px"}
小部件描述:
- 总发票 - 所有发票零售成本的总和(所有时间)和发送的发票数量
- 未付款发票 - 尚未支付的发票总和和未付款发票数量
- 本月发票 - 本日历月创建的发票总和及数量
- 上月发票 - 上日历月创建的发票总和及数量
值格式化:
- 超过 1,000 的值:显示为 "k" 后缀(例如,$1.5k)
- 超过 1,000,000 的值:显示为 "M" 后缀(例如,$2.3M)
- 超过 1,000,000,000 的值:显示为 "B" 后缀(例如,$1.1B)
趋势指标:
- "本月" 和 "上月" 的小部件显示百分比变化
- 绿色向上箭头:与上一个周期相比增加
- 红色向下箭头:与上一个周期相比减少
- 灰色向右箭头:无变化
发票列表
发票表显示所有发票,包含以下列:

列描述:
- ID - 唯一发票 ID
- 标题 - 发票标题/描述
- 期间 - 计费期间(开始日期 - 结束日期)或 "N/A" 对于一次性发票
- 到期日 - 付款到期日
- 创建 - 发票创建日期
- 金额 - 总发票金额(零售成本)
- 状态 - 已付款、未付款或已退款
- 操作 - 可用操作(根据状态有所不同)
操作图标:
- ⬇ (下载) - 下载发票 PDF
- 🗑️ (删除) - 作废发票(仅在未付款时)
- 💰 (付款) - 在线支付发票(仅在未付款时)
- ✉️ (电子邮件) - 将发票电子邮件发送给客户
- 💸 (退款) - 退款 Stripe 付款(仅适用于已付款的 Stripe 发票)
生成发票
点击 "+ 生成形式发票" 创建新发票。
{.align-center width="800px"}
字段描述:
- 搜索客户 - 选择客户(仅在系统范围视图中显示,在客户视图中预填)
- 标题 - 发票标题/名称(可选,默认为 "发票 [期间]")
- 开始日期 - 计费期间开始(默认为 14 天前)
- 结束日期 - 计费期间结束(默认为今天)
- 到期日期 - 付款截止日期(默认为今天)
- 交易预览 - 显示日期范围内所有未开票交易,并能够包括/排除特定交易
交易选择:
- ✓ (绿色加号) - 点击以从发票中排除交易
- × (红色 X) - 点击以包括先前排除的交易
- 全选 - 包括所有显示的交易
- 清除所有 - 排除所有交易
- 被排除的交易以灰色显示并带有删除线文本
- 实时总计在选择/取消选择交易时更新
发生的事情:
- 系统查找客户在日期范围内的所有未开票交易
- 显示交易预览,能够包括/排除单个交易
- 根据所选交易显示小计、税和总计的实时计算
- 仅选定(包括)的交易被添加到发票中
- 生成发票 PDF 并缓存
- 将选定交易标记为已开票(
invoice_id字段填充) - 被排除的交易保持未开票状态,并可用于将来的发票
- 发票在列表中显示为 "未付款" 状态
示例用例:
每月计费: 将开始日期设置为月初,结束日期设置为月末,预览显示该期间所有未开票交易。选择所有或手动排除特定交易。
服务特定发票: 使用相同的日期范围,然后手动排除不需要的交易(例如,排除非移动交易以创建仅移动的发票)。
一次性发票: 将开始和结束日期设置为同一天,预览仅显示该日期的交易。排除任何与此特定发票无关的费用。
查看发票详情
点击表中任何发票行以查看完整的发票详情,包括所有交易、总计和可用操作。
{.align-center width="800px"}
发票详情模态框:
- 发票信息 - 显示发票 ID、标题、日期、付款状态和作废状态
- 交易列表 - 显示发票中包含的所有交易,包含:
- 交易日期
- 标题和描述
- 零售成本
- 税额和百分比(格式为
$10.00 (10%)) - 免税交易在税列中显示 "-"
- 总计摘要 - 实时计算显示:
- 交易数量
- 小计(所有零售成本的总��)
- 税(所有税额的总和)
- 发票总计(小计 + 税)
- 操作按钮 - 与表中相同的可用操作:
- 下载 PDF - 下载发票 PDF(始终可用)
- 发送电子邮件 - 将发票通过电子邮件发送给客户(未作废的发票)
- 支付发票 - 处理付款(仅未付款、未作废的发票)
- 退款 - 退款 Stripe 付款(仅适用于已付款的 Stripe 发票)
- 删除 - 作废发票(仅适用于未付款、未作废的发票)
下载发票 PDF
点击表中的 下载图标 (⬇) 或发票详情模态框中的 "下载 PDF" 按钮以下载发票为 PDF。
下载过程:
- 点击发票旁边的下载图标
- 生成期间出现加载旋转器(仅首次)
- 浏览器提示保存文件:
Invoice_01234.pdf - PDF 打开或保存到下载文件夹
PDF 缓存行为:
- 首次下载 - 从模板生成 PDF,缓存到数据库(可能需要 2-3 秒)
- 后续下载 - 从缓存中立即下载
- 缓存失效 - 如果发票被修改或模板更新,则缓存清除
下载问题排查:
- 旋转器永远不停止 - 检查浏览器控制台,API 可能已关闭
- PDF 空白或损坏 - 检查发票模板是否有语法错误
- 下载���败 - 检查弹出窗口阻止程序设置,尝试不同的浏览器
支付发票
点击 支付图标 (💰) 在线支付发票。
{.align-center width="800px"}
支付过程:
- 点击未付款发票上的支付图标
- 支付模态框打开,显示发票详情
- 选择支付方式:
- Stripe 交易 - 收取保存的信用卡(所有用户可用)
- 现金 - 手动现金支付(仅限员工)
- 退款 - 将退款作为支付(仅限员工)
- POS 交易 - 销售终端(仅限员工)
- 银行转账 - 手动银行转账(仅限员工)
- 如果选择了 Stripe:
- 从保存的支付方式中选择卡
- 默认卡预选
- 点击选择不同的卡
- 如果选择了其他方法:
- 输入参考号码(可选)
- 点击 "支付发票" 进行处理
- 系统处理付款:
- Stripe - 通过 Stripe API 收取卡费
- 其他方法 - 为支付金额创建负交易
- 发票状态更改为 "已付款"
- 显示成功通知
自助服务与员工支付:
:doc:`自助服务门户 <self_care_portal>`(客户):
- 仅提供 Stripe 支付
- 必须有保存的支付方式
- 如果没有支付方式,将显示警告
- 提供添加支付方式的链接
员工门户(管理员):
- 提供所有支付方式
- 可以手动标记发票为已付款(现金、POS、银行转账)
- 可以输入参考号码以便跟踪
支付方式警告:
如果客户没有保存的支付方式,将显示警告提示他们在支付发票之前添加支付方式。
{.align-center width="800px"}
发送发票电子邮件
点击 电子邮件图标 (✉️) 将发票发送给客户。
发生的事情:
- 点击发票旁边的电子邮件图标
- 系统从缓存中检索发票 PDF(如果未缓存则生成)
- 通过 Mailjet 使用
api_crmCommunicationCustomerInvoice模板发送电子邮件 - 电子邮件包括:
- 附件中的发票 PDF
- 客户姓名
- 发票编号和到期日
- 应付总额
- 在线支付发票的链接
- 查看/下载发票的链接
- 成功通知:"发票电子邮件成功发送"
电子邮件收件人:
电子邮件发送给所有类型为 "billing" 的客户联系人,或如果没有账单联系人,则发送给主要联系人。
电子邮件模板变量:
{{ var:customer_name }}- 客户的全名{{ var:invoice_number }}- 发票 ID{{ var:invoice_date }}- 发票发行日期{{ var:due_date }}- 付款到期日{{ var:total_amount }}- 应付总额{{ var:invoice_url }}- 查看/下载 PDF 的链接{{ var:pay_url }}- 在线支付发票的链接
电子邮件问题排查:
- 电子邮件未发送 - 检查
crm_config.yaml中的 Mailjet API 凭证 - 客户未收到 - 验证客户联系电子邮件地址
- PDF 未附加 - 检查 PDF 生成是否成功(先尝试下载)
作废发票
点击 删除图标 (🗑️) 作废发票。
要求:
- 发票必须是 未付款
- 已付款发票不能作废(必须退款)
如何作废:
- 在列表中找到未付款发票
- 点击删除图标 (🗑️)
- 在模态框中确认:
{.align-center width="600px"}
发生的事情:
- 发票标记为
void = true - 所有交易与发票解除链接(
invoice_id设置为 null) - 交易再次变为 "未开票"
- 交易可以包含在新发票中
- 发票在列表中显示为标题前带有 "Void:" 前缀
- 发票操作被禁用(无法下载、付款或发送电子邮件)
- 可以通过筛选 "Void" 发票进行查看
重要说明:
- 作废与退款不同
- 作废 = "该发票不应存在"(账单错误,重复)
- 退款 = "撤销有效的已付款发票"(将钱退还给客户)
退款发票
点击 退款图标 (💸) 退款已付款发票。
要求:
- 发票必须是 已付款
- 发票必须通过 Stripe 付款
- 发票必须有有效的
payment_reference(Stripe 付款意图 ID) - 仅限员工用户可用(不适用于自助服务)
如何退款:
- 找到已付款的 Stripe 发票
- 点击退款图标 (💸)
- 退款确认模态框打开:
{.align-center width="800px"}
- 点击 "确认退款"
- 系统处理 Stripe 退款:
- 调用 Stripe API 退款支付
- 在 Stripe 中创建退款交易
- 更新发票以包含
refund_reference
- 发票状态更改为 "已退款"
- 显示成功通知
退款后的事情:
- 发票仍然存在于系统中(未作废)
- 状态显示为 "已退款"
- 交易仍然与发票关联
- 客户收到退款至原支付方式(3-7 个工作日)
- Stripe 仪表板显示退款交易
退款限制:
- 不能退款通过现金、POS 或银行转账支付的发票(需要手动撤销)
- 不能部分退款(仅限全额发票金额)
- 不能退款两次
搜索和筛选发票
搜索
使用搜索栏查找发票。搜索范围包括:
- 发票 ID
- 发票标题
- 客户姓名(仅限系统范围视图)
筛选
应用筛选以缩小发票列表:
可用筛选:
- 作废状态 - 全部、作废、未作废
- 付款状态 - 全部、已付款、尚未付款
筛选操作:
- 应用筛选 - 将所选筛选应用于列表
- 重置筛选 - 清除所有筛选并显示所有发票
排序
点击任何列标题进行排序:
- ID - 按发票 ID 排序(最新/最旧)
- 标题 - 按字母顺序排序
- 到期日 - 按到期日排序
- 创建 - 按创建日期排序
- 金额 - 按零售成本排序(最高/最低)
- 状态 - 按付款状态排序(已付款优先或未付款优先)
再次点击以反转排序方向(升序 ↔ 降序)。
分页
通过页面控件在大型发票列表中导航,显示当前页面、总页面和每页项目选择器(10、25、50 或 100 项)。
常见发票工作流程
工作流程 1:带交易预览的��月计费
- 月末到来(例如,1 月 31 日)
- 导航到 账单 → 发票
- 点击 "+ 生成形式发票"
- 选择客户(或如果计费多个客户则按客户操作)
- 设置日期:
- 开始日期:2025-01-01
- 结束日期:2025-01-31
- 到期日期:2025-02-15(从现在起 15 天)
- 标题:"2025 年 1 月服务"(可选)
- 交易预览 部分显示 1 月的所有未开票交易
- 审查预览:
- 默认包含所有交易
- 检查总计:小计、税和发票总计
- 验证所有费用是否正确
- 点击 "生成发票"(按钮显示交易数量,例如,"生成发票 (15)")
- 发票创建,包含所有选定交易
- 点击发票行查看详情并验证
- 点击详情模态框中的 "发送电子邮件" 按钮或表中的电子邮件图标
- 客户收到带有 PDF 和支付链接的发票电子邮件
工作流程 2:选择性交易开票
- 客户有多项服务(移动 + 互联网)和杂项费用
- 希望为每项服务开具单独的发票
- 生成第一张发票(移动服务):
- 点击 "+ 生成形式发票"
- 标题:"移动服务 - 2025 年 1 月"
- 开始/结束:1 月 1 日至 31 日
- 到期日期:2 月 15 日
- 在交易预览中,排除所有非移动交易:
- 点击互联网交易旁的 X 按钮
- 点击杂项费用旁的 X 按钮
- 仅移动服务交易保持选中
- 验证总计仅反映移动服务
- 点击 "生成发票"(显示移动交易的数量)
- 生成第二张发票(互联网服务):
- 再次点击 "+ 生成形式发票"
- 标题:"互联网服务 - 2025 年 1 月"
- 开始/结束:1 月 1 日至 31 日(相同期间)
- 在交易预览中:
- 移动交易已开票(不显示)
- 使用 X 按钮排除杂项费用
- 仅互联网服务交易保持
- 点击 "生成发票"
- 生成第三张发票(附加费用):
- 再次点击 "+ 生成形式发票"
- 标题:"附加费用 - 2025 年 1 月"
- 预览中仅显示未开票的杂项费用
- 点击 "全选" 包括所有
- 点击 "生成发票"
- 将所有三张发票发送给客户
工作流程 3:排除争议或待处理交易
- 计费期间结束
- 导航到客户 账单 标签
- 点击 "+ 生成形式发票"
- 设置��费期间日期
- 交易预览显示 20 个交易
- 客户对一项费用提出争议,另一项正在调查中
- 在交易预览中:
- 找到争议交易(例如,"数据超额费用")
- 点击 X 按钮将其排除
- 找到待处理交易(例如,"安装费用")
- 点击 X 按钮将其排除
- 交易数量更新:"选择了 18 个交易"
- 总计自动重新计算
- 审查更新后的总计(排除争议金额)
- 点击 "生成发票 (18)"
- 发票仅生成已批准的交易
- 争议/待处理交易保持未开票状态,待下一个计费周期
工作流程 4:快速发票审查和调整
- 员工生成每月发票
- 交易预览显示意外的高总计
- 审查预览中的每个交易:
- 注意到同一服务的重复收费
- 点击 X 排除重复费用
- 注意到不应计费的测试交易
- 点击 X 排除测试交易
- 总计实时更新
- 验证新总计与预期金额匹配
- 点击 "生成发票" 以更正交易
- 如果需要,返回并作废/删除排除的交易
- 将发票自信地发送给客户
工作流程 5:一次性安装发票
- 现场技术人员完成安装
- 员工手动添加安装交易
- 导航到客��� 账单 标签
- 点击 "+ 生成形式发票"
- 设置日期:
- 开始日期:今天
- 结束日期:今天
- 到期日期:今天 + 7 天
- 标题:"安装服务"
- 交易预览仅显示今天的交易
- 验证安装费用是否出现
- 使用 X 按钮排除任何重复费用(如果存在)
- 点击 "生成发票"
- 立即发送给客户
- 客户通过 Stripe 在线付款
工作流程 6:在客户联系之前查看发票
- 客户打电话询问账单问题
- 员工导航到客户的发票列表
- 点击发票行 打开发票详情模态框
- 审查发票信息:
- 发票 ID、日期、状态
- 包含的所有交易及描述
- 每个交易的税务明细
- 小计、税和总金额
- 用确切的细节回答客户的问题
- 如果客户请求 PDF,点击模态框中的 "下载 PDF" 按钮
- 如果客户请求重新发送电子邮件,点击 "发送电子邮件" 按钮
- 完成后关闭模态框
工作流程 7:更正账单错误
- 客户报告错误收费
- 员工点击发票行查看详情
- 在发票详情模态框中审查交易列表
- 确定错误交易
- 发票未付款,因此可以作废
- 点击模态框底部的 "删除" 按钮
- 确认作废
- 交易再次变为未开票
- 员工修改或删除交易列表中的错误交易
- 生成新发票,包含更正后的交易:
- 如果需要,使用交易预览排除更正后的交易
- 仅包括有效费用
- 将更正后的发票发送给客户
工作流程 8:处理多笔付款
- 客户带现金支付多张发票
- 导航到客户 账单 标签
- 查看未付款发票
- 点击第一张发票行查看详情
- 验证金额和交易
- 点击模态框底部的 "支付发票" 按钮
- 选择 "现金" 支付方式
- 输入参考:"现金支付 2025-01-15"
- 点击 "支付发票"
- 模态框关闭,发票标记为 "已付款"
- 对剩余发票重复此操作
- 所有发票现在标记为 "已付款"
工作流程 9:处理退款请求
- 客户请求退款以补偿多付
- 员工验证发票已通过 Stripe 付款
- 导航到发票列表
- 点击发票行查看详情
- 验证付款信息和金额
- 点击模态框底部的 "退款" 按钮(仅适用于 Stripe 发票)
- 确认退款
- 系统处理 Stripe 退款
- 发票状态更改为 "已退款"
- 客户在 3-7 个工作日内收到退款
- 员工跟进客户以确认收到
故障排除
无法生成发票 - 找不到交易
- 原因: 指定日期范围内没有未开票交易
- 修复: 检查交易列表,验证交易是否存在且未开票。调整日期范围或移除筛选。
发票 PDF 生成失败
- 原因: 模板语法错误、WeasyPrint 崩溃或缺少客户数据
- 修复: 检查发票模板 HTML 是否有错误,验证客户地址字段是否填充,查看 API 日志。
支付失败,出现 Stripe 错误
- 原因: 卡被拒绝、资金不足、卡过期或 Stripe API 问题
- 修复: 尝试不同的支付方式,验证卡是否有效,检查 Stripe 仪表板以获取拒绝原因。
无法作废发票
- 原因: 发票已付款
- 修复: 已付款发票无法作废。如果需要退款,请使用 Stripe 发票的退款功能或手动创建信用交易。
发票电子邮件未发送
- 原因: Mailjet API 凭证无效、客户没有账单联系人或电子邮件模板缺失
- 修复: 验证
crm_config.yaml中的 Mailjet 配置,检查客户联系人,验证发票电子邮件模板是否存在。
退款按钮未出现
- 原因: 发票通过现金/POS/银行转账支付(非 Stripe),或发票未付款
- 修复: 退款按钮仅适用于 Stripe 付款。对于其他支付方式,请创建手动信用交易。
下载 PDF 显示旧模板设计
- 原因: PDF 在模板更新之前缓存
- 修复: 清除发票 PDF 缓存:
DELETE FROM Invoice_PDF_Cache WHERE invoice_id = X;
客户无法支付发票(没有支付方式)
- 原因: 自助服务门户中没有保存的支付方式
- 修复: 客户必须在 支付方式 页面添加信用卡,然后才能支付发票。
为同一期间生成多张发票
- 原因: 员工重复生成发票,或日期范围重叠
- 修复: 作废重复发票。调整日期范围以防止重叠。使用交易预览确保唯一的交易集。
交易预览不显示交易
- 原因: 日期范围内的所有交易已开票或没有交易
- 修复: 验证日期范围是否正确。检查交易列表以确认交易是否存在。筛选发票以查看哪个发票包含交易。
无法从发票生成中排除交易
- 原因: 交易已开票或浏览器问题
- 修复: 验证交易在预览中显示并带有勾选标记。刷新页面并重试。如果问题仍然存在,请清除浏览器缓存。
发票总计与预期金额不匹配
- 原因: 包含了意外交易、税未计算或排除的交易仍被计入
- 修复: 仔细审查交易预览。检查每个交易的零售成本和税。验证排除的交易是否显示为灰色。检查生成发票按钮上的交易计数徽章。
生成发票按钮被禁用
- 原因: 没有选择交易或日期范围无效
- 修复: 确保至少包含一笔交易(未排除)。验证开始日期在结束日期之前。检查到期日期是否设置。
发票详情模态框未打开
- 原因: JavaScript 错误或页面未完全加载
- 修复: 刷新页面。检查浏览器控制台是否有错误。尝试不同的浏览器。验证互联网连接。
交易税未在发票详情中显示
- 原因: 交易的税率为 0% 或 tax_amount 为 null
- 修复: 验证交易是否设置了 tax_percentage。检查创建交易时是否计算了 tax_amount。如有需要,更新交易。
发票详情模态框中缺少操作按钮
- 原因: 发票已作废或用户缺乏权限
- 修复: 作废的发票仅显示下载 PDF 按钮。验证发票状态。检查用户角色和权限。
相关文档
integrations_mailjet- 电子邮件发票交付和模板administration_configuration- 发票模板配置payments_transaction- 创建出现在发票上的交易payments_process- 处理发票付款basics_payment- 付款方式和 Stripe 集成