feat(planning): ship holiday-aware planning and assistant upgrades
This commit is contained in:
@@ -134,12 +134,14 @@ describe("project router", () => {
|
||||
create: vi.fn().mockResolvedValue(created),
|
||||
},
|
||||
auditLog: { create: vi.fn().mockResolvedValue({}) },
|
||||
webhook: { findMany: vi.fn().mockResolvedValue([]) },
|
||||
};
|
||||
|
||||
const caller = createManagerCaller(db);
|
||||
const result = await caller.create({
|
||||
shortCode: "PRJ-001",
|
||||
name: "Test Project",
|
||||
responsiblePerson: "Alice",
|
||||
orderType: OrderType.CHARGEABLE,
|
||||
allocationType: AllocationType.INT,
|
||||
winProbability: 80,
|
||||
@@ -167,6 +169,7 @@ describe("project router", () => {
|
||||
caller.create({
|
||||
shortCode: "PRJ-001",
|
||||
name: "Duplicate",
|
||||
responsiblePerson: "Alice",
|
||||
orderType: OrderType.CHARGEABLE,
|
||||
allocationType: AllocationType.INT,
|
||||
budgetCents: 100_00,
|
||||
@@ -189,6 +192,7 @@ describe("project router", () => {
|
||||
caller.create({
|
||||
shortCode: "PRJ-002",
|
||||
name: "Blocked",
|
||||
responsiblePerson: "Alice",
|
||||
orderType: OrderType.CHARGEABLE,
|
||||
allocationType: AllocationType.INT,
|
||||
budgetCents: 100_00,
|
||||
@@ -239,6 +243,64 @@ describe("project router", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("getShoringRatio", () => {
|
||||
it("excludes regional holidays from shoring weighting", async () => {
|
||||
const db = {
|
||||
project: {
|
||||
findUnique: vi.fn().mockResolvedValue({
|
||||
id: "project_1",
|
||||
name: "Test Project",
|
||||
shoringThreshold: 55,
|
||||
onshoreCountryCode: "DE",
|
||||
}),
|
||||
},
|
||||
assignment: {
|
||||
findMany: vi.fn().mockResolvedValue([
|
||||
{
|
||||
id: "a1",
|
||||
resourceId: "res_de",
|
||||
startDate: new Date("2026-01-05T00:00:00.000Z"),
|
||||
endDate: new Date("2026-01-06T00:00:00.000Z"),
|
||||
hoursPerDay: 8,
|
||||
resource: {
|
||||
id: "res_de",
|
||||
countryId: "country_de",
|
||||
federalState: "BY",
|
||||
metroCityId: null,
|
||||
availability: { monday: 8, tuesday: 8, wednesday: 8, thursday: 8, friday: 8, saturday: 0, sunday: 0 },
|
||||
country: { id: "country_de", code: "DE" },
|
||||
metroCity: null,
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "a2",
|
||||
resourceId: "res_es",
|
||||
startDate: new Date("2026-01-05T00:00:00.000Z"),
|
||||
endDate: new Date("2026-01-06T00:00:00.000Z"),
|
||||
hoursPerDay: 8,
|
||||
resource: {
|
||||
id: "res_es",
|
||||
countryId: "country_es",
|
||||
federalState: null,
|
||||
metroCityId: null,
|
||||
availability: { monday: 8, tuesday: 8, wednesday: 8, thursday: 8, friday: 8, saturday: 0, sunday: 0 },
|
||||
country: { id: "country_es", code: "ES" },
|
||||
metroCity: null,
|
||||
},
|
||||
},
|
||||
]),
|
||||
},
|
||||
};
|
||||
|
||||
const caller = createProtectedCaller(db);
|
||||
const result = await caller.getShoringRatio({ projectId: "project_1" });
|
||||
|
||||
expect(result.totalHours).toBe(24);
|
||||
expect(result.onshoreRatio).toBe(33);
|
||||
expect(result.offshoreRatio).toBe(67);
|
||||
});
|
||||
});
|
||||
|
||||
// ─── update ───────────────────────────────────────────────────────────────
|
||||
|
||||
describe("update", () => {
|
||||
@@ -294,6 +356,7 @@ describe("project router", () => {
|
||||
project: {
|
||||
update: vi.fn().mockResolvedValue(updated),
|
||||
},
|
||||
webhook: { findMany: vi.fn().mockResolvedValue([]) },
|
||||
};
|
||||
|
||||
const caller = createManagerCaller(db);
|
||||
|
||||
Reference in New Issue
Block a user