Каждая колонка итога (D, E, F…) — это тип работ. Здесь выбирается, в какую колонку попадают значения каждого типа при сборке «Итога». Типы, не попавшие ни в одну колонку, в итоге не учитываются.
Типы coefficient складываются по коэффициентам (coef), hourly — по оплате (sum, ₽). Первая колонка подписывается «Монтаж / Демонтаж».
Страница «Итог» — это визуализация уже посчитанных данных. Сами расчёты делаются на вкладке «Расчёт зарплаты» (журнал смен) и в справочниках. «Итог» только собирает их в таблицу по шаблону Excel.
Документ каждый раз нового размера: фиксирована только шапка A1:L5, ниже — данные (4 строки на сотрудника) и смены справа.
name, venue — название и площадка (строка 1).date_start, date_end — даты (день недели смен, строка 1).employees — список {employee_id, mark, bonus}; берём только 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 (почасовая оплата). Первая колонка подписывается «Монтаж / Демонтаж».
Исключённые типы (простой, погрузка, просчёт, пульт) отдельной колонки не образуют, но их значения можно направить в любую колонку через маппинг выше.
Для каждого вида работ (обычная, Пром. альпинист, Риггер) суммируются все смены сотрудника, попавшие в колонку по маппингу:
coefficient — сумма coef (коэффициентов);hourly — сумма sum (оплаты, ₽).Сумма sum (оплаты, ₽) всех смен сотрудника, попавших в колонку по маппингу — по всем видам работ. Это фактические суммы из журнала смен, а не пересчёт «(база + надбавка) × коэф».
Шапка раздела — цвет типа (TYPE_COLORS), белый текст. Строка 9: для coefficient — цвет типа + белый текст; для hourly — прозрачный фон + цвет темы. Денежный формат (₽).
На каждую смену из project.shifts — блок из 2 колонок:
date_start проекта: смены идут парами День/Ночь, каждая пара = один день (смещение = floor(индекс / 2)); фон #4E7927, белый текст;project.shifts[i].name); фон — шапка таблицы темы (--bg-table-head);workTypesData = allWorkTypes.filter(function (t) {
return ['простой', 'погрузка', 'просчёт', 'пульт'].indexOf(t.name) === -1;
});
Остаются типы, не входящие в список: смена, дежурство, пушка.
// columnMap = { "тип": "колонка" | "" } (из config.summary_column_map)
function targetCol(typeName) {
var t = columnMap[typeName];
if (t == null) t = typeName; // по умолчанию — сам в себя
return colIndexByName[t] != null ? colIndexByName[t] : -1; // '' → не учитывается
}
Если маппинг не задан, дефолты: колонка сама в себя; «просчёт» → первая колонка; прочие исключённые → не учитываются.
var ci = targetCol(v.shift_type); if (ci < 0) return; var val = (kind === 'hourly') ? num(v.sum) : num(v.coef); typeSums[ci].sums[workKind] += val;
Почасовая оплата — сумма денег; коэффициент — сумма коэффициентов.
var ci = targetCol(v.shift_type); if (ci >= 0) typeTotals[ci] += num(v.sum);
D9:F9 — фактические суммы оплаты из журнала, а не пересчёт «(база + надбавка) × коэф».
var usedShiftNames = {};
journal.forEach(function (s) {
var name = String((s.values && s.values.shift) || '').trim();
if (name) usedShiftNames[name] = true;
});
// выводятся только смены с записями в журнале
--bg-hover), верх/низ — жирные границы.