【问题标题】:Generating Invoices生成发票
【发布时间】:2009-06-23 21:01:14
【问题描述】:

我需要大批量生成发票,这些发票将转换为 EDI 并运送到我们的总部。有一个包含所有订单的订单表。在一天中的某个时候,我必须拿一套(大约 1k)并生成发票。

  1. 生成发票编号的最佳位置是哪里?在 SQL Server 后端?或者将批次抓取到 .NET 应用程序中,然后在那里生成发票编号?发票编号可以是随机的,但不得重复(3-4 年)。我最多可以使用 12 位数字,并且可以是字母数字。在哪里可以找到有关生成发票编号的信息。

注意:在生成发票时,我需要计算订单总额和税金。

非常感谢您的意见。

【问题讨论】:

    标签: .net sql sql-server invoice


    【解决方案1】:

    发票编号可能会受到法律要求的约束(我居住的地方它们需要按顺序排列,我认为顺序中可能存在间隙)。

    您经常会看到这些数字包含一个可以及时确定其范围的元素(例如年份:200903472)。这样可以最大限度地降低使用相同数字两次的风险。

    您说您每天有大约 1000 张发票。这意味着 6 位数的发票号码将满足您的需求。所以 4 位数的年份,后跟用零填充的 6 位数发票号码可能会让您继续前进。

    我可能会让数据库生成它们以确保它们是唯一的。

    【讨论】:

    • 我如何在 sql server 中生成这个,好吧,我如何跟踪种子,以便在下一代我能够拿起最后一个。如果在发票过程中过程失败,人们将如何处理这个问题?如何回滚序列?
    • 我不是数据库专家,但我想您可以保留一张发票编号表(或者可能只存储迄今为止每年使用的最高编号的表),并有一个程序可以选择最新的,加1,存储并返回结果。但我相信还有更有效的方法。
    • 我认为最好将种子存储在数据库中。在发票过程中,我会抓取最后一个种子并从那里递增,当过程完成且没有错误时,我只需更新种子。
    • 这可能行得通,但我看到了两个弱点;您需要保证只有一个进程在处理这个问题,并且您需要处理异常,这样您就不会使用 500 个新号码,并且由于发票生成过程中的一些异常而无法更新数据库。
    【解决方案2】:

    将一个表添加到您的数据库中,该表存储上次使用的发票编号的值,以及一个用于递增该值并将新值返回给您以用于创建发票的存储过程。

    当您保存新发票时,请致电 SP 以获取下一张发票编号,这是您做的最后一件事 - 在验证通过后但立即写入磁盘之前 - 以尽量减少“编号顺序中的孔”。

    【讨论】:

    • 是的,生成没有间隙的序列很难,这关乎正确的序列。 Invoice 和 LastNum 记录的更新应该在 1 个事务中进行。
    【解决方案3】:

    使用顺序 ID 可能是最好的,除非您出于某种原因希望它们是随机的(例如因为客户不应该能够从大致相同的时间段猜测另一个订单的订单 ID)。使用顺序 ID 可以让您读取当前最大值,然后在您提交批处理订单之前检查您要写入的范围内是否没有写入任何内容。

    如果您不想承担检查数据库的负担并且可以确保其他进程不会干扰,您可以利用 DateTime.UtcNow 和 Base64 转换。一个非常笨拙的插图可能是这样的:

    Convert.ToBase64String(new byte[] { (byte)DateTime.UtcNow.Year, 
                                        (byte)DateTime.UtcNow.Month,
                                        (byte)DateTime.UtcNow.Day,
                                        (byte)DateTime.UtcNow.Hour,
                                        (byte)DateTime.UtcNow.Minute,
                                        (byte)DateTime.UtcNow.Second,
                                        (byte)DateTime.UtcNow.Millisecond })
    

    或者

    Convert.ToBase64String(new byte[] { (byte)DateTime.UtcNow.Ticks })
    

    您可能对Base32 转换更感兴趣(它使用字母 A-Z 和数字 2-7),但没有原生 .Net 转换,因此您必须搜索一个。

    【讨论】:

      【解决方案4】:

      我认为如果没有法律限制生成发票 id 的规则,它可以是任何你想要的。

      现在我有一个很好的例子:

      实际上我正在编写一个发票系统,并且我已经按顺序生成了我的 id 代码,但我发现了一些空白,因为例如当客户取消与公司的合同时,我之前已经生成了 12 张发票。

      (因为这里我们是一家 ISP 公司,合同必须是 6、12 或 24 个月)

      我的数据库中有空缺,因为系统用户删除了已取消的发票。如果我真的需要一个序列号,我就会遇到法律问题。我还有很多其他情况导致我的连续发票编号出现空白。

      我真的不知道如何避免这种问题,因为发生这种情况的情况很多。有什么想法吗?

      【讨论】:

      • 在这种情况下,我仍然可以按顺序保留发票编号,因为我从未真正删除过发票。当用户单击删除时,当然,我只是将标志从有效更改为无效。
      • 是的。你是对的,但现在对我来说已经晚了,用户已经删除了一些发票,但从现在开始,我拒绝删除操作。感谢您的提示。!
      猜你喜欢
      • 2012-04-19
      • 2012-03-07
      • 2017-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多