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