Imagine a client fills out a form, selects "Integration with 1C" without "Exchange Setup", and gets a price 40% below real. The result is either renegotiation or dissatisfaction. Our calculator avoids this. We develop project cost calculators on 1C-Bitrix. This isn't just a sum of line items—it's a tool that considers dependencies between modules, urgency coefficients, margin, and automatically sends a brief to the CRM. Such a calculator helps IT companies and agencies segment incoming leads: filter out irrelevant requests and nurture serious clients. The main problem with homemade calculators is ignoring dependencies, leading to underestimated estimates and losses during negotiation.
Over 5+ years, we've built more than 50 such solutions for studios, design bureaus, and integrators. Our calculators handle from 10 to 200 functional blocks and deliver up to 90% estimation accuracy, thanks to certified specialists and years of experience.
How we calculate project cost on Bitrix
The data model is built on HL-block ProjectBlocks. Each record is a work block with category, complexity (simple/standard/complex), hour range, and hourly rate. Dependencies and mandatory blocks are described in fields UF_DEPENDS_ON and UF_IS_REQUIRED.
| Field | Type | Description |
|---|---|---|
UF_CATEGORY |
Enum | Category (Design, Development, Integration, SEO...) |
UF_BLOCK_NAME |
String | Block name |
UF_COMPLEXITY |
Enum | simple / standard / complex |
UF_HOURS_MIN |
Int | Minimum hours |
UF_HOURS_MAX |
Int | Maximum hours |
UF_HOURLY_RATE |
Float | Hourly rate for this work type |
UF_IS_REQUIRED |
Bool | Mandatory block (always included) |
UF_DEPENDS_ON |
String | ID of dependent block (cannot be selected without it) |
More on the calculation logic
The algorithm first resolves dependencies: if a block requiring another is selected, the latter is automatically added. Then hours and cost are computed with an urgency coefficient. The final sum includes margin and is displayed as a range.Why a calculator must account for dependencies
Without dependencies, a client might choose "Mobile App Development" without "Screen Design" or "Integration with 1C" without "Exchange Setup", skewing the estimate. Our PHP calculator automatically adds missing blocks and mandatory modules.
namespace MyProject\Services\Calculators;
class ProjectCostCalculator
{
private array $blocks;
private array $selectedIds;
private float $urgencyCoeff;
private float $marginPercent;
public function __construct(
array $allBlocks,
array $selectedIds,
string $urgency = 'normal',
float $marginPercent = 30
) {
$this->blocks = $allBlocks;
$this->selectedIds = $this->resolveDependencies($selectedIds, $allBlocks);
$this->urgencyCoeff = match ($urgency) {
'urgent' => 1.5,
'fast' => 1.25,
'normal' => 1.0,
'flexible' => 0.9,
default => 1.0,
};
$this->marginPercent = $marginPercent;
}
public function calculate(): array
{
$breakdown = [];
$totalHoursMin = 0;
$totalHoursMax = 0;
$totalCost = 0;
foreach ($this->selectedIds as $blockId) {
$block = $this->findBlock($blockId);
if (!$block) continue;
$hoursMin = $block['UF_HOURS_MIN'];
$hoursMax = $block['UF_HOURS_MAX'];
$rate = $block['UF_HOURLY_RATE'];
$costMin = $hoursMin * $rate * $this->urgencyCoeff;
$costMax = $hoursMax * $rate * $this->urgencyCoeff;
$totalHoursMin += $hoursMin;
$totalHoursMax += $hoursMax;
$totalCost += ($costMin + $costMax) / 2;
$breakdown[] = [
'id' => $blockId,
'name' => $block['UF_BLOCK_NAME'],
'category' => $block['UF_CATEGORY'],
'hours' => "{$hoursMin}–{$hoursMax}",
'cost_min' => round($costMin),
'cost_max' => round($costMax),
];
}
$margin = $totalCost * ($this->marginPercent / 100);
$finalCost = $totalCost + $margin;
return [
'breakdown' => $breakdown,
'hours_min' => $totalHoursMin,
'hours_max' => $totalHoursMax,
'cost_min' => round($finalCost * 0.85),
'cost_max' => round($finalCost * 1.2),
'cost_avg' => round($finalCost),
'urgency_coeff' => $this->urgencyCoeff,
'weeks_min' => ceil($totalHoursMin / 40),
'weeks_max' => ceil($totalHoursMax / 40),
];
}
private function resolveDependencies(array $selectedIds, array $blocks): array
{
$resolved = $selectedIds;
foreach ($blocks as $block) {
if (in_array($block['ID'], $selectedIds, true) && !empty($block['UF_DEPENDS_ON'])) {
$depId = (int)$block['UF_DEPENDS_ON'];
if (!in_array($depId, $resolved, true)) {
$resolved[] = $depId;
}
}
if ($block['UF_IS_REQUIRED'] && !in_array($block['ID'], $resolved, true)) {
$resolved[] = $block['ID'];
}
}
return array_unique($resolved);
}
}
What's better: a dependency-aware calculator or a simple sum?
A simple calculator sums block prices but ignores relationships, yielding 50-60% accuracy. Our approach with automatic dependency resolution boosts accuracy to 90%—1.5-2 times better. The client gets a realistic estimate, and you get fewer renegotiations. According to our data, companies using such a calculator spend 40% less time on negotiation, which translates to significant savings when scaling.
Official 1C-Bitrix documentation on HL-blocks confirms the correctness of the data model.
How calculator development happens
- Business logic analysis: gather block list, dependencies, coefficients.
- HL-block design: create data storage infrastructure.
- Core calc implementation: PHP class with calculation and dependency resolution methods.
- CRM integration: REST API sends the brief to Bitrix24 or amoCRM.
- Interface and UX: configure checkboxes with hints and a dynamic total.
- Testing: validate with real scenarios and edge cases.
What's included in calculator development?
Each project includes:
- Designing block structure and dependencies
- Implementing HL-block and PHP calculator
- Interface with checkboxes and hints
- CRM integration (Bitrix24, amoCRM, etc.)
- Configuring brief transfer and calculation history
- Documentation and team training
Outcome: the client gets a preliminary estimate in 2 minutes, and you get a qualified lead with a filled brief.
UX: checkboxes with tooltips
The calculator interface comprises groups of checkboxes. Each checkbox has a short description so the client understands what's included.
// Update total on every change
document.querySelectorAll('.block-checkbox').forEach(cb => {
cb.addEventListener('change', async () => {
const selected = [...document.querySelectorAll('.block-checkbox:checked')]
.map(el => parseInt(el.value));
const urgency = document.querySelector('[name="urgency"]:checked').value;
const resp = await fetch('/ajax/calculator/project/', {
method: 'POST',
body: new URLSearchParams({
selected: JSON.stringify(selected),
urgency,
sessid: BX.bitrix_sessid(),
}),
});
const data = await resp.json();
updateResultPanel(data);
});
});
Transferring the brief to CRM
The calculation result forms a structured brief that immediately creates a deal in the CRM.
// Creating a deal in Bitrix24 or a lead in the site's CRM
$comments = "PROJECT COST CALCULATION\n\n";
$comments .= "Selected blocks:\n";
foreach ($calcResult['breakdown'] as $item) {
$comments .= "— {$item['category']}: {$item['name']} ({$item['hours']} hrs.)\n";
}
$comments .= "\nTotal: {$calcResult['cost_min']} – {$calcResult['cost_max']} RUB\n";
$comments .= "Timeline: {$calcResult['weeks_min']} – {$calcResult['weeks_max']} weeks\n";
$comments .= "Urgency: {$urgency}\n";
Timeline
| Task | Timeframe |
|---|---|
| Basic calculator (10–15 blocks, simple sum, request form) | 5–8 days |
| Calculator with categories, dependencies, coefficients, CRM transfer | 2–3 weeks |
| Calculator with PDF brief, calculation history, A/B tests | 4–6 weeks |
Key rule: the calculator must never quote a price below the real one. We build in a 20-30% buffer and clarify it's a preliminary estimate. This sets realistic client expectations and reduces renegotiations. Implementing such a calculator can save significant costs on each project by cutting renegotiations.
Our calculators have been battle-tested on 50+ projects—from web studios to major systems integrators. Get a free consultation and demo. Contact us to discuss your scenario.
Common mistakes in calculator development
- Ignoring mandatory blocks: without "Server Setup" for high-load projects, the estimate is too low.
- Missing dependency checks: selecting "Integration with 1C" without "Exchange Setup" leads to an incorrect total.
- Forgetting caching: under heavy load, the calculator slows down. We use tagged result caching.







