0

我有一个带有客户表的数据库。这些客户是企业,我正在尝试设计一种灵活、可靠的方式,允许客户设计自己的自定义发票编号。

例如:

  • 客户 A 发票序列:A-1306-1234,其中“A-”为静态文本,1306 为 YYMM,1234 为每月重置的序列
  • 客户 B 发票序列:123456 - 这是一个永远计数的序列
  • 客户 C 发票序列:13-123456 - 此序列有 YY-,然后序列运行一年并重置。

我正在尝试决定最灵活的方式来允许一些任意的序列成为这个数字的一​​部分。我还需要原子地生成这个数字并根据各个元素施加的固有规则来处理序列的重置,例如序列中的 MM 推断纯增量元素每月重启,其中 MMDD 推断纯增量元素每个月重启天。

自定义类型是正确的方法吗?一组 getter 和 setter 以及静态、方法和验证器?是否已经有此类功能的设计模式?

4

2 回答 2

1

我必须为客户 B 解决与您的情况类似的问题。我的解决方案:我创建了一个集合来存储序列并添加了如下文档:

{
 "_id" : "PIN",
 "_class" : "com.alldata.genIII.bo.Sequence",
 "description" : "Sequence for PIN numbers. Used in all Account collections. ",
 "nextValue" : NumberLong(100001)

}

我使用 _id 来指定 Account 集合中将使用该序列的字段。为了用户的需求,我从100001开始。

创建帐户时,我获取序列的下一个值并更新序列加 1。此操作是原子的,因为我使用findAndModify

这是我的代码(在 java 中)来获取序列的下一个值:

    public Long fetchNextValue(String sequenceId) {
        Update update = new Update();
        update.inc("nextValue", 1);
        Sequence seq = mongoTemplate.findAndModify(new Query(Criteria.where("code").is(sequenceId)), update, Sequence.class);
        if (seq == null)
            throw new NotFoundException("Sequence not found for sequenceId " + sequenceId);
        return seq.getNextValue();
    }

我有这个代码在生产中运行,到目前为止我还没有遇到问题。但以防万一,我在帐户集合的“pin”字段中放置了一个唯一索引,因此如果有重复,我会捕获异常并使用新的 pin 重试几次。

有关如何完成此操作的更多信息,请查看本文

对于其他情况,您可以使用存储在 mongoDB 中的 javascript 函数,将该逻辑应用于序列。看看这篇文章,虽然现在有一条消息说他们不推荐它(那条消息是新的......)但它可以给你更多的想法。

希望这可以帮助

于 2013-06-26T14:03:43.473 回答
0

我用一个比我开始寻找的简单得多的解决方案实现了我的目标。在每个机构记录中,我创建了一个名为invoice_format. 在此字段中,我存储了一个格式字符串,我解析该字符串以生成发票编号。例如:

invoice_format: "A-{YY}{seq-04.d}"

我对此进行解析,{} 内的任何内容都被视为格式规则,{} 之外的任何内容都被视为文字文本。我有一个不那么华丽的开关,它可以查找每个格式化规则并根据规则返回一个值。我还有工作要做,但这构成了我的序列生成器的基础。每个客户的序列都保存在一个单独的字段中,称为 invoice_sequence,当我在某个字段中遇到 {seq} 时,我会增加该字段并返回结果。

于 2013-06-27T15:34:05.860 回答