Страница «Итог» — это визуализация уже посчитанных данных. Сами расчёты делаются на вкладке «Расчёт зарплаты» (журнал смен) и в справочниках. «Итог» только собирает их в таблицу по шаблону Excel.
Документ каждый раз нового размера: фиксирована только шапка A1:L5, ниже — данные (4 строки на сотрудника) и смены справа.
name, venue — название и площадка (строка 1).date_start, date_end — даты (день недели смен, строка 1).employees — список {employee_id, mark}; берём только mark = "V" (галочка), в порядке списка.shifts — список смен {name, type, start, end} (правые колонки).name — «Фамилия Имя» → разбиваем: первое слово = Фамилия, остальное = Имя.position — должность (колонка B).employment — занятость: «Не устроен» / «ИП» / «Самозанятый» (колонка B и базовая ставка).employee_id, shift_type (тип смены), work_kind (вид работ), coef (коэффициент), sum (оплата).employee_id и work_kind.base_rates — базовая ставка: {должность: {занятость: ставка}}.allowances — надбавки: {должность: {вид работ: сумма}}.Каждый сотрудник занимает 4 строки, начиная с 6-й:
| Строка | A (Сотрудник) | B (Должность) | C (Базовая ставка) |
|---|---|---|---|
| 1-я | Фамилия | Должность + Занятость | Базовая ставка |
| 2-я | Имя | Должность + Занятость + Пром. альпинист | Базовая ставка + надбавка (Пром. альпинист) |
| 3-я | пусто | Должность + Занятость + Риггер | Базовая ставка + надбавка (Риггер) |
| 4-я | пусто | пусто | пусто |
Вид «обычная» в колонке B подразумевается, но не пишется. Занятость «Не устроен» держим для расчёта, но в тексте не выводим.
Из name сотрудника: первое слово → Фамилия (строка 1), остальное → Имя (строка 2), строки 3–4 пустые. Текст жирный, фон — выделенный блок темы (--bg-selected), внутренние границы блока невидимы.
Должность + Занятость + Вид работы. Занятость «Не устроен» в тексте не выводится.
base_rates[должность][занятость];allowances[должность]["Пром. альпинист"];allowances[должность]["Риггер"];Колонки D, E, F… — это типы работ из справочника work_types. У каждого типа есть kind: coefficient (коэффициент) или hourly (почасовая оплата). Первая колонка подписывается «Монтаж / Демонтаж».
Для каждого вида работ (обычная, Пром. альпинист, Риггер) суммируются все смены сотрудника с shift_type = тип:
coefficient — сумма coef (коэффициентов);hourly — сумма sum (оплаты, ₽).Сумма sum (оплаты, ₽) всех смен сотрудника с shift_type = тип — по всем видам работ. Это фактические суммы из журнала смен, а не пересчёт «(база + надбавка) × коэф».
Для первой колонки дополнительно прибавляется сумма по сменам shift_type = «просчёт»: в строки 6–8 — коэффициент, в строку 9 — оплата.
Шапка раздела — цвет типа (TYPE_COLORS), белый текст. Строка 9: для coefficient — цвет типа + белый текст; для hourly — прозрачный фон + цвет темы. Денежный формат (₽).
На каждую смену из project.shifts — блок из 2 колонок:
date_start проекта: смены идут парами День/Ночь, каждая пара = один день (смещение = floor(индекс / 2)); фон #4E7927, белый текст;project.shifts[i].name); фон — шапка таблицы темы (--bg-table-head);workTypesData = (res[2] || []).filter(function (t) {
return ['простой', 'погрузка', 'просчёт', 'пульт'].indexOf(t.name) === -1;
});
Остаются типы, не входящие в список: смена, дежурство, пушка.
if ((v.shift_type || '') === wt.name) {
var val = (kind === 'hourly') ? num(v.sum) : num(v.coef);
sums[workKind] = (sums[workKind] || 0) + val;
}
Почасовая оплата — сумма денег; коэффициент — сумма коэффициентов.
if ((v.shift_type || '') === td.name) {
total += num(v.sum);
}
D9:F9 — фактические суммы оплаты из журнала, а не пересчёт «(база + надбавка) × коэф».
if (ADD_PROSCHET_COEF_TO_MONTAZH) {
montazh.sums[wk] += num(v.coef); // строки 6–8: коэффициент
typeTotals[0] += num(v.sum); // строка 9: оплата (₽)
}
Смены «просчёт» складываются в первую колонку («Монтаж / Демонтаж»).
var usedShiftNames = {};
journal.forEach(function (s) {
var name = String((s.values && s.values.shift) || '').trim();
if (name) usedShiftNames[name] = true;
});
// выводятся только смены с записями в журнале
--bg-hover), верх/низ — жирные границы.