@outbuild-company/schedule-core 1.14.1 → 1.14.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -15088,6 +15088,9 @@ async function dispatchBulkEdit(action, options, deps) {
15088
15088
  const trackingEvents = [];
15089
15089
  const linkChanges = [];
15090
15090
  const warnings = [];
15091
+ const warningsBeforeExplicitConstraint = /* @__PURE__ */ new Set();
15092
+ const appliedDateColumnsByActivity = /* @__PURE__ */ new Map();
15093
+ const explicitConstraintsByActivity = /* @__PURE__ */ new Map();
15091
15094
  let needsAutoSchedule = false;
15092
15095
  for (const edit of action.edits) {
15093
15096
  const outcome = applyOneEdit2(edit, deps, action.eventSource);
@@ -15105,6 +15108,7 @@ async function dispatchBulkEdit(action, options, deps) {
15105
15108
  if (isExplicitConstraintDateEdit(edit.column)) {
15106
15109
  explicitDateEditActivities.add(String(edit.activityId));
15107
15110
  }
15111
+ recordAppliedDateColumn(appliedDateColumnsByActivity, edit);
15108
15112
  const beforeLinkLags = snapshotIncomingLinkLags(adapter, edit.activityId);
15109
15113
  const preEditSnapshot = snapshotSingleActivity(
15110
15114
  adapter,
@@ -15119,6 +15123,16 @@ async function dispatchBulkEdit(action, options, deps) {
15119
15123
  adapter,
15120
15124
  preEditSnapshot
15121
15125
  );
15126
+ recordWarningsBeforeExplicitConstraint(
15127
+ warningsBeforeExplicitConstraint,
15128
+ warnings,
15129
+ edit
15130
+ );
15131
+ recordExplicitConstraint(
15132
+ explicitConstraintsByActivity,
15133
+ edit,
15134
+ adapter.getActivity(edit.activityId)
15135
+ );
15122
15136
  syncCustomIdTracker(edit, customIdBeforeApply, deps);
15123
15137
  linkChanges.push(
15124
15138
  ...diffIncomingLinkLagChanges(beforeLinkLags, adapter, edit.activityId)
@@ -15138,6 +15152,14 @@ async function dispatchBulkEdit(action, options, deps) {
15138
15152
  now: deps.now,
15139
15153
  options
15140
15154
  };
15155
+ const reconciledWarnings = reconcileAtomicDateConstraints(
15156
+ appliedDateColumnsByActivity,
15157
+ explicitConstraintsByActivity,
15158
+ beforeSnap,
15159
+ warnings,
15160
+ warningsBeforeExplicitConstraint,
15161
+ deps
15162
+ );
15141
15163
  const batchHasConstraintEdits = constraintPriorsByActivity.size > 0;
15142
15164
  const { scheduledIds } = await (batchHasConstraintEdits ? settleConstraintEdits(
15143
15165
  {
@@ -15181,11 +15203,114 @@ async function dispatchBulkEdit(action, options, deps) {
15181
15203
  sirDetection: SIR_DETECTION_PHASE.BEFORE_DIFF,
15182
15204
  links: linkChanges,
15183
15205
  trackingEvents,
15184
- warnings,
15206
+ warnings: reconciledWarnings,
15185
15207
  hoursPerDay: sector.hoursPerDay
15186
15208
  })
15187
15209
  };
15188
15210
  }
15211
+ function recordWarningsBeforeExplicitConstraint(warningsBeforeExplicitConstraint, warnings, edit) {
15212
+ if (!isConstraintEditColumn(edit.column)) return;
15213
+ const activityId = String(edit.activityId);
15214
+ for (const warning of warnings) {
15215
+ if (String(warning.activityId) === activityId) {
15216
+ warningsBeforeExplicitConstraint.add(warning);
15217
+ }
15218
+ }
15219
+ }
15220
+ function recordExplicitConstraint(constraintsByActivity, edit, activity) {
15221
+ if (!isConstraintEditColumn(edit.column) || !activity) return;
15222
+ constraintsByActivity.set(String(edit.activityId), {
15223
+ constraintType: activity.constraintType,
15224
+ constraintDate: activity.constraintDate ? new Date(activity.constraintDate.getTime()) : null
15225
+ });
15226
+ }
15227
+ function recordAppliedDateColumn(columnsByActivity, edit) {
15228
+ if (edit.column !== COLUMN.START_DATE && edit.column !== COLUMN.END_DATE) {
15229
+ return;
15230
+ }
15231
+ const activityId = String(edit.activityId);
15232
+ const columns = columnsByActivity.get(activityId) ?? /* @__PURE__ */ new Set();
15233
+ columns.add(edit.column);
15234
+ columnsByActivity.set(activityId, columns);
15235
+ }
15236
+ function reconcileAtomicDateConstraints(columnsByActivity, explicitConstraintsByActivity, beforeSnap, warnings, warningsBeforeExplicitConstraint, deps) {
15237
+ const reconciledIds = /* @__PURE__ */ new Set();
15238
+ const reconciledWarnings = [];
15239
+ const discardedWarnings = /* @__PURE__ */ new Set();
15240
+ for (const [activityId, columns] of columnsByActivity) {
15241
+ if (!columns.has(COLUMN.START_DATE) || !columns.has(COLUMN.END_DATE)) {
15242
+ continue;
15243
+ }
15244
+ const explicitConstraint = explicitConstraintsByActivity.get(activityId);
15245
+ if (explicitConstraint) {
15246
+ deps.adapter.setActivityFields(activityId, explicitConstraint);
15247
+ for (const warning of warningsBeforeExplicitConstraint) {
15248
+ if (String(warning.activityId) === activityId) {
15249
+ discardedWarnings.add(warning);
15250
+ }
15251
+ }
15252
+ continue;
15253
+ }
15254
+ const before = beforeSnap.get(activityId);
15255
+ const after = deps.adapter.getActivity(activityId);
15256
+ if (!before?.constraintType || !before.constraintDate || !after) continue;
15257
+ const projectedDate = pickProjectedDateForConstraint(
15258
+ before.constraintType,
15259
+ after.startDate,
15260
+ after.endDate
15261
+ );
15262
+ const violatesConstraint = violatesAtomicDateConstraint(
15263
+ before.constraintType,
15264
+ before.constraintDate,
15265
+ projectedDate
15266
+ );
15267
+ reconciledIds.add(activityId);
15268
+ if (violatesConstraint) {
15269
+ deps.adapter.setActivityField(
15270
+ activityId,
15271
+ "constraintType",
15272
+ CONSTRAINT_TYPE.SNET
15273
+ );
15274
+ deps.adapter.setActivityField(
15275
+ activityId,
15276
+ "constraintDate",
15277
+ new Date(after.startDate.getTime())
15278
+ );
15279
+ const warning = toConstraintWarning(
15280
+ activityId,
15281
+ buildConstraintNotification(
15282
+ before.constraintType,
15283
+ before.constraintDate,
15284
+ projectedDate
15285
+ )
15286
+ );
15287
+ if (warning) reconciledWarnings.push(warning);
15288
+ continue;
15289
+ }
15290
+ deps.adapter.setActivityField(
15291
+ activityId,
15292
+ "constraintType",
15293
+ before.constraintType
15294
+ );
15295
+ deps.adapter.setActivityField(
15296
+ activityId,
15297
+ "constraintDate",
15298
+ before.constraintDate
15299
+ );
15300
+ }
15301
+ return [
15302
+ ...warnings.filter(
15303
+ (warning) => !discardedWarnings.has(warning) && !reconciledIds.has(String(warning.activityId))
15304
+ ),
15305
+ ...reconciledWarnings
15306
+ ];
15307
+ }
15308
+ function violatesAtomicDateConstraint(constraintType, constraintDate, projectedDate) {
15309
+ if (constraintType === CONSTRAINT_TYPE.MSO || constraintType === CONSTRAINT_TYPE.MFO) {
15310
+ return constraintDate.getTime() !== projectedDate.getTime();
15311
+ }
15312
+ return checkConstraintViolation(constraintType, constraintDate, projectedDate).violated;
15313
+ }
15189
15314
  function applyOneEdit2(edit, deps, eventSource) {
15190
15315
  const { ctx } = deps;
15191
15316
  const activityId = edit.activityId;