|
1 |
| -import { Book, parseScripture } from '@seedcompany/scripture'; |
| 1 | +import { Book, parseScripture, Range, Verse } from '@seedcompany/scripture'; |
2 | 2 | import { Cell } from '~/common/xlsx.util';
|
3 | 3 | import { ScriptureRange } from '../scripture/dto';
|
| 4 | +import { PnpExtractionResult } from './extraction-result'; |
4 | 5 | import { PlanningSheet } from './planning-sheet';
|
5 | 6 | import { ProgressSheet } from './progress-sheet';
|
6 | 7 |
|
7 |
| -export const isGoalRow = (cell: Cell<PlanningSheet | ProgressSheet>) => { |
| 8 | +export const isGoalRow = ( |
| 9 | + cell: Cell<PlanningSheet | ProgressSheet>, |
| 10 | + result?: PnpExtractionResult, |
| 11 | +) => { |
8 | 12 | if (cell.sheet.isOBS()) {
|
9 | 13 | return !!cell.sheet.storyName(cell.row);
|
10 | 14 | }
|
11 | 15 | if (!cell.sheet.isWritten()) {
|
12 | 16 | return false;
|
13 | 17 | }
|
14 | 18 |
|
15 |
| - const rawBook = cell.sheet.bookName(cell.row); |
16 |
| - const versesToTranslate = cell.sheet.totalVerses(cell.row) ?? 0; |
| 19 | + const bookCell = cell.sheet.bookName(cell.row); |
| 20 | + const versesCell = cell.sheet.totalVerses(cell.row); |
| 21 | + const rawBook = bookCell.asString; |
| 22 | + const versesToTranslate = versesCell.asNumber ?? 0; |
17 | 23 |
|
18 | 24 | if (versesToTranslate <= 0) {
|
19 | 25 | return false;
|
20 | 26 | }
|
21 | 27 |
|
22 |
| - // Try as book name first since it's faster than parsing scripture string |
23 |
| - const maybeBook = rawBook ? Book.namedMaybe(rawBook) : undefined; |
| 28 | + if (!rawBook) { |
| 29 | + result?.addProblem({ |
| 30 | + severity: 'Warning', |
| 31 | + groups: 'No book name given', |
| 32 | + message: `Ignoring row with no book name \`${bookCell.ref}\` even though there are **${versesToTranslate}** verses to translate \`${versesCell.ref}\``, |
| 33 | + source: cell, |
| 34 | + }); |
| 35 | + return false; |
| 36 | + } |
| 37 | + |
| 38 | + // Try as book name first since it is faster than parsing scripture string |
| 39 | + // And ensure total verses given is plausible |
| 40 | + const maybeBook = Book.namedMaybe(rawBook); |
24 | 41 | if (maybeBook) {
|
25 |
| - // Sanity check to ensure total verses given is plausible |
26 |
| - return versesToTranslate <= maybeBook.totalVerses; |
| 42 | + const validVerseCount = versesToTranslate <= maybeBook.totalVerses; |
| 43 | + !validVerseCount && |
| 44 | + result?.addProblem({ |
| 45 | + severity: 'Error', |
| 46 | + groups: 'The verses to translate exceeds total verses in book', |
| 47 | + message: `Ignoring _${maybeBook.name}_ because **${versesToTranslate}** \`${versesCell.ref}\` verses to translate exceeds the total number of verses in the book`, |
| 48 | + source: cell, |
| 49 | + }); |
| 50 | + return validVerseCount; |
27 | 51 | }
|
28 | 52 |
|
29 |
| - let scriptureRanges; |
| 53 | + let parsedRange = true; |
| 54 | + let scriptureRanges: ReadonlyArray<Range<Verse>> = []; |
30 | 55 | try {
|
31 | 56 | scriptureRanges = parseScripture(rawBook);
|
32 | 57 | } catch {
|
| 58 | + parsedRange = false; |
| 59 | + } |
| 60 | + if (!parsedRange || scriptureRanges.length === 0) { |
| 61 | + result?.addProblem({ |
| 62 | + severity: 'Error', |
| 63 | + groups: 'Could not determine book reference', |
| 64 | + message: `"${rawBook}" \`${bookCell.ref}\` could not be identified as a book name or scripture reference`, |
| 65 | + source: cell, |
| 66 | + }); |
33 | 67 | return false;
|
34 | 68 | }
|
35 | 69 |
|
36 |
| - const totalVersesInRange = ScriptureRange.totalVerses(...scriptureRanges); |
37 |
| - |
38 | 70 | // Treat range(s) as valid if the total verses represented
|
39 |
| - // equals what's been given in the other column. |
40 |
| - return versesToTranslate === totalVersesInRange; |
| 71 | + // equals what has been given in the other column. |
| 72 | + const totalVersesInRange = ScriptureRange.totalVerses(...scriptureRanges); |
| 73 | + const validRange = totalVersesInRange === versesToTranslate; |
| 74 | + if (!validRange) { |
| 75 | + addProblemMismatchScriptureAndVerseCount( |
| 76 | + result, |
| 77 | + totalVersesInRange, |
| 78 | + bookCell, |
| 79 | + versesCell, |
| 80 | + ); |
| 81 | + } |
| 82 | + return validRange; |
41 | 83 | };
|
| 84 | + |
| 85 | +export function addProblemMismatchScriptureAndVerseCount( |
| 86 | + result: PnpExtractionResult | undefined, |
| 87 | + parsedVerseCount: number, |
| 88 | + book: Cell, |
| 89 | + totalVerses: Cell, |
| 90 | +) { |
| 91 | + result?.addProblem({ |
| 92 | + severity: 'Error', |
| 93 | + groups: |
| 94 | + 'Mismatch between the planned scripture in _Books_ column and the number of verses to translate', |
| 95 | + message: `"${book.asString!}" \`${ |
| 96 | + book.ref |
| 97 | + }\` is **${parsedVerseCount}** verses, but the goal declares **${totalVerses.asNumber!}** verses to translate \`${ |
| 98 | + totalVerses.ref |
| 99 | + }\``, |
| 100 | + source: book, |
| 101 | + }); |
| 102 | +} |
0 commit comments