@hed-hog/operations 0.0.331 → 0.0.332

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.
Files changed (62) hide show
  1. package/dist/controllers/operations-collaborators.controller.d.ts +54 -0
  2. package/dist/controllers/operations-collaborators.controller.d.ts.map +1 -1
  3. package/dist/controllers/operations-collaborators.controller.js +100 -0
  4. package/dist/controllers/operations-collaborators.controller.js.map +1 -1
  5. package/dist/dto/create-collaborator-invoice.dto.d.ts +11 -0
  6. package/dist/dto/create-collaborator-invoice.dto.d.ts.map +1 -0
  7. package/dist/dto/create-collaborator-invoice.dto.js +55 -0
  8. package/dist/dto/create-collaborator-invoice.dto.js.map +1 -0
  9. package/dist/dto/create-collaborator-payment.dto.d.ts +10 -0
  10. package/dist/dto/create-collaborator-payment.dto.d.ts.map +1 -0
  11. package/dist/dto/create-collaborator-payment.dto.js +50 -0
  12. package/dist/dto/create-collaborator-payment.dto.js.map +1 -0
  13. package/dist/dto/list-collaborator-invoice.dto.d.ts +4 -0
  14. package/dist/dto/list-collaborator-invoice.dto.d.ts.map +1 -0
  15. package/dist/dto/list-collaborator-invoice.dto.js +8 -0
  16. package/dist/dto/list-collaborator-invoice.dto.js.map +1 -0
  17. package/dist/dto/list-collaborator-payment.dto.d.ts +4 -0
  18. package/dist/dto/list-collaborator-payment.dto.d.ts.map +1 -0
  19. package/dist/dto/list-collaborator-payment.dto.js +8 -0
  20. package/dist/dto/list-collaborator-payment.dto.js.map +1 -0
  21. package/dist/dto/update-collaborator-invoice.dto.d.ts +6 -0
  22. package/dist/dto/update-collaborator-invoice.dto.d.ts.map +1 -0
  23. package/dist/dto/update-collaborator-invoice.dto.js +9 -0
  24. package/dist/dto/update-collaborator-invoice.dto.js.map +1 -0
  25. package/dist/dto/update-collaborator-payment.dto.d.ts +6 -0
  26. package/dist/dto/update-collaborator-payment.dto.d.ts.map +1 -0
  27. package/dist/dto/update-collaborator-payment.dto.js +9 -0
  28. package/dist/dto/update-collaborator-payment.dto.js.map +1 -0
  29. package/dist/operations.service.d.ts +76 -0
  30. package/dist/operations.service.d.ts.map +1 -1
  31. package/dist/operations.service.js +235 -5
  32. package/dist/operations.service.js.map +1 -1
  33. package/hedhog/data/menu.yaml +27 -8
  34. package/hedhog/data/route.yaml +72 -0
  35. package/hedhog/frontend/app/_components/collaborator-form-screen.tsx.ejs +39 -3
  36. package/hedhog/frontend/app/_components/collaborator-invoices-tab.tsx.ejs +443 -0
  37. package/hedhog/frontend/app/_components/collaborator-payment-history-tab.tsx.ejs +429 -0
  38. package/hedhog/frontend/app/_components/my-project-summary-screen.tsx.ejs +86 -87
  39. package/hedhog/frontend/app/_components/project-assignments-tab.tsx.ejs +218 -10
  40. package/hedhog/frontend/app/_components/project-details-screen.tsx.ejs +710 -26
  41. package/hedhog/frontend/app/_components/project-form-screen.tsx.ejs +158 -38
  42. package/hedhog/frontend/app/_components/task-detail-sheet.tsx.ejs +807 -803
  43. package/hedhog/frontend/app/_lib/api.ts.ejs +631 -480
  44. package/hedhog/frontend/app/_lib/types.ts.ejs +6 -5
  45. package/hedhog/frontend/app/_lib/utils/task-ui.ts.ejs +18 -0
  46. package/hedhog/frontend/app/my-projects/page.tsx.ejs +16 -2
  47. package/hedhog/frontend/app/my-tasks/page.tsx.ejs +95 -157
  48. package/hedhog/frontend/app/projects/page.tsx.ejs +42 -6
  49. package/hedhog/frontend/app/tasks-gantt/page.tsx.ejs +953 -0
  50. package/hedhog/frontend/messages/en.json +96 -2
  51. package/hedhog/frontend/messages/pt.json +96 -2
  52. package/hedhog/table/operations_collaborator_invoice.yaml +35 -0
  53. package/hedhog/table/operations_collaborator_payment.yaml +32 -0
  54. package/package.json +5 -5
  55. package/src/controllers/operations-collaborators.controller.ts +117 -8
  56. package/src/dto/create-collaborator-invoice.dto.ts +39 -0
  57. package/src/dto/create-collaborator-payment.dto.ts +35 -0
  58. package/src/dto/list-collaborator-invoice.dto.ts +3 -0
  59. package/src/dto/list-collaborator-payment.dto.ts +3 -0
  60. package/src/dto/update-collaborator-invoice.dto.ts +6 -0
  61. package/src/dto/update-collaborator-payment.dto.ts +6 -0
  62. package/src/operations.service.ts +328 -5
@@ -2695,6 +2695,265 @@ export class OperationsService {
2695
2695
  );
2696
2696
  }
2697
2697
 
2698
+ async getCollaboratorPaymentHistory(
2699
+ userId: number,
2700
+ collaboratorId: number,
2701
+ ) {
2702
+ const actor = await this.getActorContext(userId);
2703
+ this.ensureDirector(actor);
2704
+ await this.getCollaboratorById(collaboratorId);
2705
+
2706
+ const rows = await this.prisma.operations_collaborator_payment.findMany({
2707
+ where: { collaborator_id: collaboratorId },
2708
+ orderBy: { payment_date: 'desc' },
2709
+ });
2710
+
2711
+ return rows.map((r) => ({
2712
+ id: r.id,
2713
+ collaboratorId: r.collaborator_id,
2714
+ amount: r.amount.toString(),
2715
+ paymentDate: r.payment_date,
2716
+ referenceMonth: r.reference_month,
2717
+ paymentMethod: r.payment_method,
2718
+ notes: r.notes,
2719
+ createdAt: r.created_at,
2720
+ }));
2721
+ }
2722
+
2723
+ async getCollaboratorInvoices(
2724
+ userId: number,
2725
+ collaboratorId: number,
2726
+ ) {
2727
+ const actor = await this.getActorContext(userId);
2728
+ this.ensureDirector(actor);
2729
+ await this.getCollaboratorById(collaboratorId);
2730
+
2731
+ const rows = await this.prisma.operations_collaborator_invoice.findMany({
2732
+ where: { collaborator_id: collaboratorId },
2733
+ orderBy: { issue_date: 'desc' },
2734
+ });
2735
+
2736
+ return rows.map((r) => ({
2737
+ id: r.id,
2738
+ collaboratorId: r.collaborator_id,
2739
+ invoiceNumber: r.invoice_number,
2740
+ amount: r.amount.toString(),
2741
+ issueDate: r.issue_date,
2742
+ dueDate: r.due_date,
2743
+ status: r.status,
2744
+ description: r.description,
2745
+ createdAt: r.created_at,
2746
+ }));
2747
+ }
2748
+
2749
+ async createCollaboratorPayment(
2750
+ userId: number,
2751
+ collaboratorId: number,
2752
+ data: {
2753
+ amount: number;
2754
+ paymentDate: string;
2755
+ referenceMonth?: string | null;
2756
+ paymentMethod?: string;
2757
+ notes?: string | null;
2758
+ },
2759
+ ) {
2760
+ const actor = await this.getActorContext(userId);
2761
+ this.ensureDirector(actor);
2762
+ await this.getCollaboratorById(collaboratorId);
2763
+
2764
+ const created = await this.prisma.operations_collaborator_payment.create({
2765
+ data: {
2766
+ collaborator_id: collaboratorId,
2767
+ amount: data.amount,
2768
+ payment_date: new Date(data.paymentDate),
2769
+ reference_month: data.referenceMonth ?? null,
2770
+ payment_method: (data.paymentMethod ?? 'pix') as any,
2771
+ notes: data.notes ?? null,
2772
+ },
2773
+ });
2774
+
2775
+ return {
2776
+ id: created.id,
2777
+ collaboratorId: created.collaborator_id,
2778
+ amount: created.amount.toString(),
2779
+ paymentDate: created.payment_date,
2780
+ referenceMonth: created.reference_month,
2781
+ paymentMethod: created.payment_method,
2782
+ notes: created.notes,
2783
+ createdAt: created.created_at,
2784
+ };
2785
+ }
2786
+
2787
+ async updateCollaboratorPayment(
2788
+ userId: number,
2789
+ collaboratorId: number,
2790
+ paymentId: number,
2791
+ data: Partial<{
2792
+ amount: number;
2793
+ paymentDate: string;
2794
+ referenceMonth: string | null;
2795
+ paymentMethod: string;
2796
+ notes: string | null;
2797
+ }>,
2798
+ ) {
2799
+ const actor = await this.getActorContext(userId);
2800
+ this.ensureDirector(actor);
2801
+
2802
+ const payment = await this.prisma.operations_collaborator_payment.findFirst({
2803
+ where: { id: paymentId, collaborator_id: collaboratorId },
2804
+ });
2805
+ if (!payment) throw new NotFoundException('Payment record not found.');
2806
+
2807
+ const updated = await this.prisma.operations_collaborator_payment.update({
2808
+ where: { id: paymentId },
2809
+ data: {
2810
+ ...(data.amount !== undefined && { amount: data.amount }),
2811
+ ...(data.paymentDate !== undefined && { payment_date: new Date(data.paymentDate) }),
2812
+ ...('referenceMonth' in data && { reference_month: data.referenceMonth }),
2813
+ ...(data.paymentMethod !== undefined && { payment_method: data.paymentMethod as any }),
2814
+ ...('notes' in data && { notes: data.notes }),
2815
+ },
2816
+ });
2817
+
2818
+ return {
2819
+ id: updated.id,
2820
+ collaboratorId: updated.collaborator_id,
2821
+ amount: updated.amount.toString(),
2822
+ paymentDate: updated.payment_date,
2823
+ referenceMonth: updated.reference_month,
2824
+ paymentMethod: updated.payment_method,
2825
+ notes: updated.notes,
2826
+ createdAt: updated.created_at,
2827
+ };
2828
+ }
2829
+
2830
+ async deleteCollaboratorPayment(
2831
+ userId: number,
2832
+ collaboratorId: number,
2833
+ paymentId: number,
2834
+ ) {
2835
+ const actor = await this.getActorContext(userId);
2836
+ this.ensureDirector(actor);
2837
+
2838
+ const payment = await this.prisma.operations_collaborator_payment.findFirst({
2839
+ where: { id: paymentId, collaborator_id: collaboratorId },
2840
+ });
2841
+ if (!payment) throw new NotFoundException('Payment record not found.');
2842
+
2843
+ await this.prisma.operations_collaborator_payment.delete({
2844
+ where: { id: paymentId },
2845
+ });
2846
+
2847
+ return { success: true };
2848
+ }
2849
+
2850
+ async createCollaboratorInvoice(
2851
+ userId: number,
2852
+ collaboratorId: number,
2853
+ data: {
2854
+ invoiceNumber?: string | null;
2855
+ amount: number;
2856
+ issueDate: string;
2857
+ dueDate?: string | null;
2858
+ status?: string;
2859
+ description?: string | null;
2860
+ },
2861
+ ) {
2862
+ const actor = await this.getActorContext(userId);
2863
+ this.ensureDirector(actor);
2864
+ await this.getCollaboratorById(collaboratorId);
2865
+
2866
+ const created = await this.prisma.operations_collaborator_invoice.create({
2867
+ data: {
2868
+ collaborator_id: collaboratorId,
2869
+ invoice_number: data.invoiceNumber ?? null,
2870
+ amount: data.amount,
2871
+ issue_date: new Date(data.issueDate),
2872
+ due_date: data.dueDate ? new Date(data.dueDate) : null,
2873
+ status: (data.status ?? 'pending') as any,
2874
+ description: data.description ?? null,
2875
+ },
2876
+ });
2877
+
2878
+ return {
2879
+ id: created.id,
2880
+ collaboratorId: created.collaborator_id,
2881
+ invoiceNumber: created.invoice_number,
2882
+ amount: created.amount.toString(),
2883
+ issueDate: created.issue_date,
2884
+ dueDate: created.due_date,
2885
+ status: created.status,
2886
+ description: created.description,
2887
+ createdAt: created.created_at,
2888
+ };
2889
+ }
2890
+
2891
+ async updateCollaboratorInvoice(
2892
+ userId: number,
2893
+ collaboratorId: number,
2894
+ invoiceId: number,
2895
+ data: Partial<{
2896
+ invoiceNumber: string | null;
2897
+ amount: number;
2898
+ issueDate: string;
2899
+ dueDate: string | null;
2900
+ status: string;
2901
+ description: string | null;
2902
+ }>,
2903
+ ) {
2904
+ const actor = await this.getActorContext(userId);
2905
+ this.ensureDirector(actor);
2906
+
2907
+ const invoice = await this.prisma.operations_collaborator_invoice.findFirst({
2908
+ where: { id: invoiceId, collaborator_id: collaboratorId },
2909
+ });
2910
+ if (!invoice) throw new NotFoundException('Invoice not found.');
2911
+
2912
+ const updated = await this.prisma.operations_collaborator_invoice.update({
2913
+ where: { id: invoiceId },
2914
+ data: {
2915
+ ...('invoiceNumber' in data && { invoice_number: data.invoiceNumber }),
2916
+ ...(data.amount !== undefined && { amount: data.amount }),
2917
+ ...(data.issueDate !== undefined && { issue_date: new Date(data.issueDate) }),
2918
+ ...('dueDate' in data && { due_date: data.dueDate ? new Date(data.dueDate) : null }),
2919
+ ...(data.status !== undefined && { status: data.status as any }),
2920
+ ...('description' in data && { description: data.description }),
2921
+ },
2922
+ });
2923
+
2924
+ return {
2925
+ id: updated.id,
2926
+ collaboratorId: updated.collaborator_id,
2927
+ invoiceNumber: updated.invoice_number,
2928
+ amount: updated.amount.toString(),
2929
+ issueDate: updated.issue_date,
2930
+ dueDate: updated.due_date,
2931
+ status: updated.status,
2932
+ description: updated.description,
2933
+ createdAt: updated.created_at,
2934
+ };
2935
+ }
2936
+
2937
+ async deleteCollaboratorInvoice(
2938
+ userId: number,
2939
+ collaboratorId: number,
2940
+ invoiceId: number,
2941
+ ) {
2942
+ const actor = await this.getActorContext(userId);
2943
+ this.ensureDirector(actor);
2944
+
2945
+ const invoice = await this.prisma.operations_collaborator_invoice.findFirst({
2946
+ where: { id: invoiceId, collaborator_id: collaboratorId },
2947
+ });
2948
+ if (!invoice) throw new NotFoundException('Invoice not found.');
2949
+
2950
+ await this.prisma.operations_collaborator_invoice.delete({
2951
+ where: { id: invoiceId },
2952
+ });
2953
+
2954
+ return { success: true };
2955
+ }
2956
+
2698
2957
  async listDepartments(
2699
2958
  userId: number,
2700
2959
  filters: {
@@ -3118,6 +3377,17 @@ export class OperationsService {
3118
3377
  AND LOWER(TRIM(p2.name)) = LOWER(TRIM(p.client_name))
3119
3378
  LIMIT 1)
3120
3379
  ) AS "clientAvatarId",
3380
+ COALESCE(
3381
+ client_user.photo_id,
3382
+ (SELECT u2.photo_id
3383
+ FROM person p2
3384
+ JOIN person_user pu2 ON pu2.person_id = p2.id
3385
+ JOIN "user" u2 ON u2.id = pu2.user_id
3386
+ WHERE p.client_person_id IS NULL
3387
+ AND LOWER(TRIM(p2.name)) = LOWER(TRIM(p.client_name))
3388
+ ORDER BY pu2.id ASC
3389
+ LIMIT 1)
3390
+ ) AS "clientUserPhotoId",
3121
3391
  p.summary,
3122
3392
  p.status,
3123
3393
  p.progress_percent AS "progressPercent",
@@ -3135,13 +3405,21 @@ export class OperationsService {
3135
3405
  LEFT JOIN operations_contract c ON c.id = p.contract_id
3136
3406
  LEFT JOIN operations_collaborator m ON m.id = p.manager_collaborator_id
3137
3407
  LEFT JOIN person cp ON cp.id = p.client_person_id
3408
+ LEFT JOIN LATERAL (
3409
+ SELECT u.photo_id
3410
+ FROM person_user pu
3411
+ JOIN "user" u ON u.id = pu.user_id
3412
+ WHERE pu.person_id = p.client_person_id
3413
+ ORDER BY pu.id ASC
3414
+ LIMIT 1
3415
+ ) client_user ON TRUE
3138
3416
  LEFT JOIN person mp ON mp.id = m.person_id
3139
3417
  LEFT JOIN operations_project_assignment pa
3140
3418
  ON pa.project_id = p.id
3141
3419
  AND pa.deleted_at IS NULL
3142
3420
  AND pa.status IN ('planned', 'active')
3143
3421
  WHERE ${whereClause}
3144
- GROUP BY p.id, c.id, m.id, cp.id, mp.id`;
3422
+ GROUP BY p.id, c.id, m.id, cp.id, mp.id, client_user.photo_id`;
3145
3423
 
3146
3424
  if (!pagination) {
3147
3425
  return this.queryRows(`${baseQuery} ORDER BY p.name ASC`, params);
@@ -8637,6 +8915,17 @@ export class OperationsService {
8637
8915
  AND LOWER(TRIM(p2.name)) = LOWER(TRIM(p.client_name))
8638
8916
  LIMIT 1)
8639
8917
  ) AS "clientAvatarId",
8918
+ COALESCE(
8919
+ client_user.photo_id,
8920
+ (SELECT u2.photo_id
8921
+ FROM person p2
8922
+ JOIN person_user pu2 ON pu2.person_id = p2.id
8923
+ JOIN "user" u2 ON u2.id = pu2.user_id
8924
+ WHERE p.client_person_id IS NULL
8925
+ AND LOWER(TRIM(p2.name)) = LOWER(TRIM(p.client_name))
8926
+ ORDER BY pu2.id ASC
8927
+ LIMIT 1)
8928
+ ) AS "clientUserPhotoId",
8640
8929
  p.code,
8641
8930
  p.name,
8642
8931
  p.client_name AS "clientName",
@@ -8658,6 +8947,14 @@ export class OperationsService {
8658
8947
  LEFT JOIN operations_contract c ON c.id = p.contract_id
8659
8948
  LEFT JOIN operations_collaborator m ON m.id = p.manager_collaborator_id
8660
8949
  LEFT JOIN person client_person ON client_person.id = p.client_person_id
8950
+ LEFT JOIN LATERAL (
8951
+ SELECT u.photo_id
8952
+ FROM person_user pu
8953
+ JOIN "user" u ON u.id = pu.user_id
8954
+ WHERE pu.person_id = p.client_person_id
8955
+ ORDER BY pu.id ASC
8956
+ LIMIT 1
8957
+ ) client_user ON TRUE
8661
8958
  LEFT JOIN operations_project_assignment pa
8662
8959
  ON pa.project_id = p.id
8663
8960
  AND pa.deleted_at IS NULL
@@ -8673,7 +8970,7 @@ export class OperationsService {
8673
8970
  ) project_role_locale ON TRUE
8674
8971
  WHERE p.id = $1
8675
8972
  AND p.deleted_at IS NULL
8676
- GROUP BY p.id, c.id, m.id, client_person.id`,
8973
+ GROUP BY p.id, c.id, m.id, client_person.id, client_user.photo_id`,
8677
8974
  [projectId, actorCollaboratorId ?? null],
8678
8975
  );
8679
8976
 
@@ -9440,7 +9737,14 @@ export class OperationsService {
9440
9737
  from_status,
9441
9738
  to_status,
9442
9739
  created_at
9443
- ) VALUES ($1, $2, $3, $4, $5, NOW())`,
9740
+ ) VALUES (
9741
+ $1,
9742
+ $2,
9743
+ $3::operations_task_activity_action_bd50457330_enum,
9744
+ $4::operations_task_activity_from_status_3a69262de6_enum,
9745
+ $5::operations_task_activity_to_status_1fd99321c8_enum,
9746
+ NOW()
9747
+ )`,
9444
9748
  params.taskId,
9445
9749
  params.actorCollaboratorId,
9446
9750
  params.action,
@@ -10449,7 +10753,7 @@ export class OperationsService {
10449
10753
  created_at,
10450
10754
  updated_at
10451
10755
  ) VALUES (
10452
- $1, $2, $3, $4, $5, $6, $7::date, $8::date,
10756
+ $1, $2, $3, $4, $5::numeric, $6::numeric, $7::date, $8::date,
10453
10757
  $9::operations_project_assignment_status_155b459bbf_enum,
10454
10758
  NOW(), NOW()
10455
10759
  )`,
@@ -12549,6 +12853,17 @@ export class OperationsService {
12549
12853
  AND LOWER(TRIM(p2.name)) = LOWER(TRIM(p.client_name))
12550
12854
  LIMIT 1)
12551
12855
  ) AS "clientAvatarId",
12856
+ COALESCE(
12857
+ client_user.photo_id,
12858
+ (SELECT u2.photo_id
12859
+ FROM person p2
12860
+ JOIN person_user pu2 ON pu2.person_id = p2.id
12861
+ JOIN "user" u2 ON u2.id = pu2.user_id
12862
+ WHERE p.client_person_id IS NULL
12863
+ AND LOWER(TRIM(p2.name)) = LOWER(TRIM(p.client_name))
12864
+ ORDER BY pu2.id ASC
12865
+ LIMIT 1)
12866
+ ) AS "clientUserPhotoId",
12552
12867
  p.summary,
12553
12868
  p.status,
12554
12869
  p.progress_percent AS "progressPercent",
@@ -12562,12 +12877,20 @@ export class OperationsService {
12562
12877
  LEFT JOIN operations_contract c ON c.id = p.contract_id
12563
12878
  LEFT JOIN operations_collaborator m ON m.id = p.manager_collaborator_id
12564
12879
  LEFT JOIN person cp ON cp.id = p.client_person_id
12880
+ LEFT JOIN LATERAL (
12881
+ SELECT u.photo_id
12882
+ FROM person_user pu
12883
+ JOIN "user" u ON u.id = pu.user_id
12884
+ WHERE pu.person_id = p.client_person_id
12885
+ ORDER BY pu.id ASC
12886
+ LIMIT 1
12887
+ ) client_user ON TRUE
12565
12888
  LEFT JOIN operations_project_assignment pa
12566
12889
  ON pa.project_id = p.id
12567
12890
  AND pa.deleted_at IS NULL
12568
12891
  AND pa.status IN ('planned', 'active')
12569
12892
  WHERE ${whereClause}
12570
- GROUP BY p.id, c.id, m.id, cp.id`;
12893
+ GROUP BY p.id, c.id, m.id, cp.id, client_user.photo_id`;
12571
12894
 
12572
12895
  if (!pagination) {
12573
12896
  return this.queryRows(`${baseQuery} ORDER BY p.name ASC`, params);