人们喜欢送货。 只需支付一小笔费用,您便有机会在不离开家的情况下获得必要的商品:您最喜欢的餐厅提供的食物,超大家具,想长时间阅读的书以及其他任何东西。 而且,世界上一切事物快速交付的服务数量的增加也证实了这一论点。 是的,对于商店来说,这是一个加分-他与任何将货物运送到门上的伙伴合作,并增加了支票。
我们在“十字路口”有自己的交付。 对于外面的人来说,从商店到房屋的交付过程如下所示:
- 我在网站上选择了一些东西,然后放入了篮子。
- 我输入了地址并为订单付款。
- 商店迅速将订单下达给快递员。
- 快递员下了订单。
实际上,一切都有些复杂。 我叫Vitaliy,我是开发部门的负责人,今天我将告诉您一切对我们有效。 还有什么。

两个应用程序负责流程的稳定性-展示柜和用户移动应用程序。 店面里的一切都很经典-买家访问网站,花一些时间选择产品并装满篮子,检查产品卡。 这里的最后一步是下订单。 之后,订单被转移到后台处理。
通常,在线商店的后台是一种对商品执行很多动作的系统:我们规定商品在某些促销中的参与程度,将标语与此相关联,突出显示品牌区域等等。 当然,订单在这里处理。 当买方完成订购过程并且订单到达后台办公室时,必须进行确认。 如果我们已经知道该买家,或者由操作员按照常规方案“您好,您在这里订购了一些东西,确认,数据是否正确吗?”,就会自动发生这种情况。 到此为止,后台办公人员在完成交货过程中的参与已经结束,确认了订单,状态从“已处理”更改为“执行中”。 WMS中的订单(其中没有保留的,已收集的,已订购的商品,无法从供应商处订购,并已从供应商处订购),与此同时,物流管理人员可以开始发送该订单。 总的来说,WMS和物流是与订单并行工作的独立系统。
同时,有现货
WMS系统是我们的软件,仓库,这些仓库的员工和设备的组合,极大地简化了这些员工的生活。 安装在员工手腕上的小型终端机使您可以按所需顺序快速组装订单。

一致性很重要,因为我们在特殊的Crossroads盒子中向客户交付订单。 盒子里有东西-它是矩形的。 像大多数盒子一样。
因此,有必要同时观察两个条件-尽可能多地填充盒子,这样客户就不会收到只有一半装满的两个盒子(这既不经济,对环境又不陌生,并且通常很奇怪),并按照“从重到轻”的原则填充盒子”。 该系统考虑了产品尺寸及其包装。 知道了这一点和box参数之后,就可以形成订单,以便将box填充到最大。 这样一来,您可以摆脱快递员的车似乎已将所有100%装满货箱,但一半都空了的货箱替换掉的情况。
并且系统以什么顺序为仓库工作人员收集订单。 很少有人想得到一个能使一个好的仓库员工在最底下放三个鸡蛋的盒子,例如,小心地在10包牛奶和几公斤蔬菜上放鸡蛋。 当然,有了牛奶,一切都会好起来的,这不能说是鸡蛋。 各种各样的易碎Cookie始终位于顶部。

另外,您必须遵守商品附近的规定。 假设您订购了2种苹果,面包卷和鱼,这一切会让您感到非常难过,而且所有这些东西不是和鱼一起散发出来,而是与洗涤剂一起散发出来,因为所有东西都装在一个盒子里。 因此,食品-分开,家用化学品-分开。 顺便说一下,商品的邻域由SanPiN标准确定。 我们观察他们。 从人类的角度来看,这是一个逻辑且唯一的真实模型。 从仓库的角度来看,这些是构建仓库工人路线时的其他变量。
该系统将所有因素都考虑在内并建立一条路线,因此,员工可以按期望的顺序收集订单-终端将他引导到正确的货架上。 如果您夸大其词,则该应用程序的客户端部分的工作看起来像是这样:“伙计,去B4,拿5包面粉,把它们放在盒子的底部。 然后从A2抢牛奶。 不,不是这个,那是在那个牢房里。”

一旦他们为仓库管理员提出申请,就有必要为快递员提出申请。 它不仅有助于构建路线,而且还有助于在此过程中快速打印支票并记录订单的新状态。 好吧,指标,没有指标-我们可以查看特定快递员的位置,他通常是否适合日程安排,是否将订单转移给买方时打印了一张支票,依此类推。

顺便说一句,为什么我们不立即打印支票:当我们将包装箱带给客户时,他可以出于任何原因拒绝任何产品。 例如,他设法出去为自己买冰淇淋,或者立刻煮了两升牛奶,并决定今晚吃鱼和腌黄瓜只是一个主意。 通常,拒绝任何立场可能有很多原因,包括“改变主意”。 因此,快递员将删除客户拒绝的职位,并打印最终支票。
引擎盖下
我们在Swift和Kotlin(分别为iOS和Android)上编写应用程序。 在这种情况下,整个后端都使用PHP旋转,因此我们决定在Postgres上建立数据库,对于代理,我们有Rabbit mq。
是的,很明显,在2019年,每个人都将基于移动优先原则进行所有操作,但不知何故,该网站越来越近,越来越贵。 他在Lavarel工作。 在微服务的方向上,我们也刚刚开始发展,因此现在站点和应用程序都是如此庞大的整体,它坐着等待它已经被拉开以用于微服务。
顺便提一下,提到的Postgres有时会显示为瓶颈,因此我们将进行一些更改。 我们积极使用平衡器,因为系统上的负载可能具有非常不同的值。
所有这些东西都以这种形式方便地位于服务器上:
16个具有PHP-FPM和Postgres的应用程序服务器,Postgres具有1个主服务器和4个从服务器。 如您所见,没有自行车。 整个后台均与内部系统(WMS,仓库,物流,会计和营销)完全集成。
我们于2017年推出了移动应用程序和网站。 今天,系统的平均负载约为每天6,000个订单。 一方面,它不是很多,另一方面,仍然值得考虑的是,它在24小时内分布不均匀,人们没有全天候点菜,在工作时间还可以进行标准活动。 PHP查询本身(包括API)在5分钟内大约有70,000。
订单路径
一旦订单在仓库成功组装好并准备旅行,就将其发送出去。 现在我们开始使用Yandex.Routing-这是一个很好的产品,它使我们能够在考虑交通状况的情况下快速为驾驶员建立最佳路线-交通拥堵,天气,地板,障碍物和其他乐趣。 这可以帮助我们节省燃料,从而使快递员不会在城市周围打圈。 驾驶员有一条清晰的路线,列出了订单的运输清单,订单本身以相同的顺序交付到汽车中。

正如我已经写过的,我们在Kotlin上为Android快递员制作了应用程序。 就是在其中缝制了路由,与客户进行通信的能力(我们隐藏了客户的电话号码,驾驶员只有“呼叫”按钮),编辑订单和删除物品,打印支票并支付订单费用的能力。

另外,关于遥测:应用程序考虑了所有内容:旅行时间,到达客户的时间和出发时间,这极大地有助于构建大量分析报告并跟踪物流。 例如,快递员不动一段时间,但总的来说他应该-他们联系他并指定一切是否正常。 在这方面,与物流的联系非常重要,因为在某些情况下,快递员应在一个地址,例如15:00,在另一个地址:15.30。 但是在第一个地址,由于院子里的访问控制,障碍或大门而出了麻烦,我不得不花额外的10分钟时间与客户联系,以便客户联系安全等等,您知道这是怎么发生的。

但从客户15.30的角度来看,这根本不是他的问题,他正在指定的时间等待订单。 因此,驾驶员联系后勤人员,他们特别密切地监视他的遥测,并且他们自己联系下一个客户,并指定由于障碍物卡住导致的交货时间间隔。 当然,无论如何,快递员迟到都是可悲的。 但是,当他迟到并且不对此进行警告时,情况甚至更糟。
通常,如果这是基本的,这就是我们的工作方式。 您可能对了解仓库和WMS的操作,或者对于驱动程序或仓库工人的应用程序,或者对路由感兴趣,然后对它们感兴趣,然后将其写在评论中,我将在另一篇文章中发表。
感谢您的阅读。