【问题标题】:How to generate Order Numbers in commercetools如何在 commercetools 中生成订单号
【发布时间】:2018-08-04 10:41:51
【问题描述】:

当我在 commercetools API(此处记录:http://dev.commercetools.com/http-api-projects-orders.html#create-order-from-cart)上从购物车创建订单时,我必须手动设置 orderNumber。 Number 很重要,因为商务工具平台的内部 ID 是长 UUID,在履行和支付过程中不实用。

可靠地生成顺序递增且唯一的订单号的最佳方法是什么(在这种情况下没有外部系统生成它们,最好不必为此案例引入一个)?

【问题讨论】:

  • 平台本身没有办法。该数字可能应该指某种外部系统订单号。因此,如果您在没有外部系统的情况下自行使用 commercetools,则需要在系统中添加一些内容以提供序列号。如果您不需要序列号,则需要使用真正随机的 ID 生成器 - ShortID 可能会工作 https://github.com/dylang/shortid - 您可以在浏览器中使用它。或者,您可能会提出功能请求以支持平台中的序列生成器。其他电子商务平台也得到了它;)

标签: commercetools


【解决方案1】:

执行此操作的一个好方法是使用自定义对象来包含您的顺序订单号。在创建订单时,您可以尝试更新此自定义对象 http://dev.commercetools.com/http-api-projects-custom-objects.html#create-or-update-a-customobject。如果更新成功,您可以使用该数字作为 orderNumber,如果失败,请递增并重试。

回顾一下: 当您要将购物车变成订单时,请从您的自定义对象中获取当前订单号。然后,尝试增加它。如果成功,则使用该编号作为订单的 orderNumber。

【讨论】:

【解决方案2】:

正如@svaj 所说,您可以使用自定义对象获取客户或订单的序列号。由于版本,自定义对象将充当锁,避免两个并发请求可能获得相同的数字。如果出现并发错误,您也可以使用递归重试。

这是 ES6 中的一个工作示例(同样适用于订单号)。您唯一需要设置的是 sequence 的名称,它将成为自定义对象的容器和键(例如“customerSequence”)。

setCustomerNumber({ sequence, value, version }) {
  return customObjectsService
    .save({
      container: sequence,
      key: sequence,
      value,
      version,
    })
    .then(customObject => customObject.value);
},

getCustomerNumber(sequence) {
  return customObjectsService
    .find({ where: `key="${sequence}"` })
    .then(({ results }) => (results.length ? results[0] : { value: 0 }))
    .then(lastValue => {
      return this.setCustomerNumber({
        sequence,
        value: lastValue.value + 1,
        version: lastValue.version,
      }).catch(() => this.getCustomerNumber(sequence)); // We request a new one on error
    });
},

这里你有前面代码的单元测试

describe('when getting the next customer number', () => {
  const sequence = 'customersSequence';

  describe('when existing previous customer number', () => {
    const oldCustomerNumber = 1;
    const newCustomerNumber = oldCustomerNumber + 1;
    const version = 1;

    beforeEach(() => {
      spyOn(customObjectsService, 'find').and.returnValue(
        Promise.resolve({
          results: [
            {
              value: oldCustomerNumber,
              version,
            },
          ],
          total: 1,
        }),
      );
      spyOn(customersService, 'setCustomerNumber').and.returnValue(
        Promise.resolve(newCustomerNumber),
      );
    });

    it('should get a customer number equals to <previous customer number> + 1', done => {
      customersService
        .getCustomerNumber(sequence)
        .then(customerNumber => {
          expect(customObjectsService.find).toHaveBeenCalledWith({
            where: `key="${sequence}"`,
          });
          expect(customersService.setCustomerNumber).toHaveBeenCalledWith({
            sequence,
            value: newCustomerNumber,
            version,
          });
          expect(customerNumber).toBe(newCustomerNumber);
        })
        .then(done, done.fail);
    });
  });

  describe('when NOT existing previous customer number', () => {
    const newCustomerNumber = 1;

    beforeEach(() => {
      spyOn(customObjectsService, 'find').and.returnValue(
        Promise.resolve({
          results: [],
          total: 0,
        }),
      );
      spyOn(customersService, 'setCustomerNumber').and.returnValue(
        Promise.resolve(newCustomerNumber),
      );
    });

    it('should get a customer number equals to 1', done => {
      customersService
        .getCustomerNumber(sequence)
        .then(customerNumber => {
          expect(customObjectsService.find).toHaveBeenCalledWith({
            where: `key="${sequence}"`,
          });
          expect(customersService.setCustomerNumber).toHaveBeenCalledWith({
            sequence,
            value: newCustomerNumber,
            version: undefined,
          });
          expect(customerNumber).toBe(newCustomerNumber);
        })
        .then(done, done.fail);
    });
  });
});

【讨论】:

  • 不要回复答案。而是通过留下链接、评论(当你有声望,如果这个人问这个问题,别担心他们看到你...
【解决方案3】:

如果您使用 Java 编写集成(使用 CommerceTools Java SDK),那么您可以使用 java.util.concurrent.atomic.AtomicLong。这是一个在 CommerceTools 中创建订单后为其设置订单号的示例。

首先像这样在你的类中定义一个静态变量

private static final AtomicLong sequence = new AtomicLong(System.currentTimeMillis() / 1000);

那么这可以用在这样的方法中

public void setOrderNumber(Order order) throws ShoppingCartException {
    long orderNumber = sequence.incrementAndGet();

    // command to set order number
    SetOrderNumber action = SetOrderNumber.of(String.valueOf(orderNumber));
    OrderUpdateCommand command = OrderUpdateCommand.of(order, action);

    // execute the command
    try {
        // some code to get a Java SDK client
        BlockingSphereClient client = ...;
        this.order = client.executeBlocking(command);
    } catch (Exception e) {
        // log/throw exeception
    }
}

【讨论】:

  • 不胜感激的原因。
猜你喜欢
  • 1970-01-01
  • 2011-04-27
  • 2017-01-28
  • 1970-01-01
  • 2018-09-01
  • 1970-01-01
  • 2019-06-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多