Case 01 · wholesale & distribution · wholesale distributor of furniture hardware, ufa

The very first run surfaced 18 debtors and 143 SKUs the warehouse was short of. Until then, nobody had seen it

Receivablesnever tracked18 debtors
Tasks for sales repsfrom memory20 a day
Match with 1Cfigures disagreedwithin 0.2%

Results from a specific project, not a guarantee of similar outcomes.

Context

A wholesale distributor of furniture hardware in Ufa: around six hundred active customers, five sales reps, an eight-figure monthly sales target in rubles. A healthy, profitable business — and one that ran entirely on what particular people happened to remember.

A customer would stop ordering, and nobody noticed for months — by which point they were already buying from a competitor. Nobody tracked receivables systematically: the books showed gross debt as a single number, and no one could see the real picture customer by customer. Purchase orders to suppliers were placed by eye, so part of the range was out of stock while another part had years of inventory sitting on the shelves.

Management, meanwhile, had no daily plan vs. actual. Reports from 1C (the ERP/accounting system standard in Russia) were compiled by hand and disagreed with reality, because different people counted by different methods. Arguments about the numbers had to be settled before any argument about decisions could begin.

The brief was simple: make the system find the problems in the data by itself and turn them into specific tasks for specific sales reps. Not a dashboard nobody looks at, but deals in the CRM that cannot be ignored.

Constraints

  • No writes to 1C. Ever. A non-negotiable requirement from the owner. The accounting system is the source of truth for the bookkeepers, and any write from outside calls it into question
  • The CRM — allowlist only. Nine permitted write operations; everything else is rejected. The LLM agent physically cannot write to Bitrix24, however much it might want to
  • A live database with a history of its own. The main warehouse ID in the spec turned out to be wrong and pointed at a showroom warehouse. The “Invoice for payment” document didn’t exist in the database at all. The order-payments register was empty. The “Manager” field in documents was mostly filled with a technical “Administrator” account — so there was no standard way to tell whose customer was whose
  • The portal’s robots clashed with the bot, overwriting the assignee and service fields on freshly created deals
  • A daily model budget of $15 — once it runs out, the system must degrade to template briefs, not stop
  • The spec kept changing on the fly. The replenishment formula was revised three times in a single day; the set of analytical tracks, twice in one week

Solution

What it delivers

Every morning a sales rep opens the CRM and sees a new deal. In it: a specific customer, the reason for reaching out, and a ready-made call brief — what this customer bought before, what their average order looked like item by item with SKU codes, which of the items they need are in stock right now, and what the goal of the conversation is.

The rep doesn’t have to search for anything. No need to remember who hasn’t been called in a while. No need to open 1C and stitch reports together. The work comes to them on its own, one task at a time.

In the evening, management gets the day’s results: plan vs. actual for the company and for every rep, average order value by customer category, and the effectiveness of each track — how many tasks were issued, how many were worked, how many turned into shipments.

How it works

At the core of the system are five “growth tracks”. Every morning the bot sweeps the entire customer base and finds: dormant customers, product groups with a sales drop, customers with a narrow basket (buying two product groups when they could be buying fifteen), new customers with no repeat purchase. Each finding becomes a deal — no more than one per rep per day on each track, so the team isn’t buried under a useless flood.

A separate call-out track works as a conveyor: the rep gets the next dormant customer only after logging the outcome on the previous one. That is fundamentally different from exporting a “call someday” list, which always ends up as dead weight.

Money is covered by two more tracks. Receivables are collected weekly across all of a customer’s legal entities at once — through the customer-to-counterparty link, because one buyer can be registered under three different legal entities. The debtor’s deal goes to their rep with the amount and an attached breakdown by document. Replenishment reconciles free stock — net of reserves for orders already accepted — against the client’s target levels and attaches the result as a file straight into a deal for the purchasing manager.

A separate part of the work that usually goes unshown is reconciliation control. Revenue as computed by the bot was checked against the accounting benchmark: a discrepancy of 0.2%. Plan vs. actual matched the client’s own file to the kopeck. Free stock was checked by the owner by hand on a specific SKU, and the figures matched. Without this procedure, any automated analytics is just one more source of disputed numbers.

On top of everything sits a conversational mode. An allowlisted employee asks a free-form question: “analyze transfers to the production warehouse”, “who owes us money”. The agent builds the queries to the accounting system itself, does the math and answers with reconciled figures. Heavy analyses go to an analytical sandbox with SQL and Excel output.

Try it yourself

An AI employee’s morning — in 30 seconds

Below is a scaled-down copy of the system running on fictional data. On the left, what the agent sees in 1C and Bitrix24; on the right, its feed. Start the run and watch: each finding highlights its data, every problem gets a task with a ready-made brief, and at the end it all rolls up into that same morning report for management.

Architecture

The read-only path to 1C is a double barrier. The client physically has no write methods, and an interceptor rejects any non-GET request before it is sent. A nightly sync lands the data in a local cache: around nineteen thousand shipments over thirteen months, document lines, stock levels, prices, reference data. All analytics runs off the cache — the accounting system takes no load at all.

The CRM allowlist is code. Nine write operations, each a separate typed method with validation before the network call. The generic API call and the LLM agent can only read. This turned out to be the strongest argument in the conversation with the client: not a promise that “the bot won’t break anything”, but an architectural impossibility.

Profiles of both systems. The bot mapped the structure of the accounting system (791 objects) and the portal (62 entities, 2,356 fields, 108 stages) on its own, checks for changes weekly and reports discrepancies. The semantics of deal stages come from the profile rather than being hard-coded — so changes in the CRM don’t break the reports.

Cascading rep attribution. Since the field in the documents is useless, a customer’s real rep is reconstructed from account assignments and shipment history. Coverage: 89.8%.

Idempotency everywhere. The deal journal is written before the API call, so a restart creates no duplicates. Reports have dispatch keys. Re-running any job is safe.

The LLM layer is isolated. The agent runs under a daily budget and degrades to templates when it is exhausted. The briefs in deals are built on the same data as the reports — the model does no arithmetic of its own. That is a matter of principle: code does the counting, the model does the wording.

Stack

Python 3.12asyncioaiogram1C ODataBitrix24 RESTSQLiteAPSchedulerClaude APIDocker334 unit tests

Outcome

From kick-off to live autonomous operation: about two weeks.

The first receivables run identified 18 debtors and created nine deals without a single error. The first automated stock reconciliation showed that for 143 of 301 SKUs free stock was below a month’s consumption — while other items were frozen for years ahead, up to three hundred months of supply. The returns report surfaced a quarter of a million rubles of excess stock and an item to send back to the supplier.

Along the way, things nobody suspected got cleaned up: 148 customers wrongly linked to someone else’s CRM records and 42 ghost customers in the analytics.

Today the system creates up to twenty deals a day and runs with no human involved. On the very first day of the call-out track, the reps worked through seven customers it handed them.

A separate outcome is repeatability. The project profile estimates deploying a copy for a new client at three to four days of development plus three to four days of configuration.

MetricBeforeAfter
Receivablesnot tracked systematically18 debtors on the first run
Stock reconciliationordering by eye143 of 301 SKUs to reorder
Shipment attributionfield useless89.8% coverage
Bad links in the CRM148 wrongcleaned up
Time to autonomous mode—~2 weeks

What I’d do differently

  • A formula from the spec produced the opposite result — testing on live data saved it. The selection rule in the replenishment module, written to the letter of the spec, put overstocked items on the order and skipped items with zero stock. It was caught before launch only because every calculation was run on real stock levels and eyeballed. Any business formula has to be checked on edge cases before production, not after
  • “Stock” is three different numbers. I started with “on hand”, while the client works with free stock net of reserves. On one SKU the difference was 148 units versus 45. Warehouse terms need to be pinned down with the client on a concrete example, not in a message thread
  • A deploy killed the evening digest. A container rebuild landed on the exact minute the scheduler fired. The schedule lives in process memory, the run was lost, the reports never went out. Now there are deployment windows and a mandatory check of the dispatch log after every rebuild
  • The company matcher linked people by patronymic. 148 wrong links; deals were going to the wrong customer. The rules for individuals were rewritten — full name including surname only — and a post-check for name compatibility was added
  • The first one-off report went out in the wrong shape: it included all items with stock instead of only unsold ones, 1,153 items instead of 105. For one-off reports, check not just the figures but the selection itself — against the client’s sample
  • The spec has a life of its own. The replenishment formula changed three times in one day. The project survived only because every threshold and rule lives in configuration — most of the changes were made without a single line of code

What it means in money

The first run surfaced 18 debtors and 143 short-stocked SKUs — money that was already sitting in your 1C. Don’t take my word for it — move the sliders to fit your business:

Run it on your own numbers

Average order value40,000 ₽
Active customers400
Go silent per quarter5 customers
Revenue quietly walking out with churning customers9,600,000 ₽ a year

That's 5% of your customer base a year — and all of this data is already sitting in your 1C. If the system keeps just three of them, that's 1,440,000 ₽ in annual revenue — the “Analytics + CRM” package (380,000 ₽) pays for itself in about 13 months.

Formula: churned customers × 4 quarters × average order × 12 orders a year (conservatively, one order a month); payback assumes a 25% margin. An estimate, not a guarantee: the exact figure comes from your data during discovery.

After that, all you pay is the monthly fee — less than one sales rep.

Where next

People also look at

Bitrix24 + Telegram · client project

AI Sales Supervisor

exports and pivot tablesa question in Telegram

The CEO talks to the CRM like a live analyst: pipeline, revenue by source, rep KPIs — the answer comes back as a finished report. The system watches unanswered leads and stalled deals on its own — 1,815 deals under control. The third system built for this client.

read the case study →
Prices, no call needed

AI Sales Employee pricing

Implementation 240,000 – 540,000 ₽ · support from 45,000 ₽/mo · 40/30/30 milestone payments tied to results

Common question
How long does it take?
A working pilot — usually two weeks. Then iterations on live data: in the 1C + Bitrix24 case study the system went autonomous just two weeks after kickoff.

Need time to think it over?

Take this case study as a single file — easy to forward to a colleague or bring to a meeting. The link appears instantly.

Sound familiar — the data is in 1C, but decisions are made from memory?

Get in touch — in one conversation we'll find where the money sits in your 1C and CRM, and where to start.

I reply the same day, usually within a couple of hours.