Files
PowderCoatingLogix/src/PowderCoating.Application/Interfaces/IFormulaLibraryService.cs
T
spouliot ed35362c7a Add Formula Library ratings, Job Profitability report, and Quote Revision History improvements
- Formula Library ratings: thumbs up/down per company per formula; toggle on/off; sorts by net score; own formulas not rateable; FormulaLibraryRating entity + migration AddFormulaLibraryRatings
- Job Profitability report: actual labor cost (logged hours x StandardLaborRate) vs powder cost vs billed price per job; gross margin % color-coded; time-tracked-only filter; totals footer
- Quote Revision History: track Total price changes on every save; log Sent/Resent events with recipient email; replace flat table with grouped timeline UI (icons per event type, total-change badge on header)
- Setup Wizard: cap CompletedCount at TotalSteps so old 10-step data no longer shows 10/5
- Formula Library card: fix badge overflow on long titles; add Rate: label to make voting buttons discoverable
- Help docs and AI knowledge base updated for all three features

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 09:02:07 -04:00

62 lines
2.7 KiB
C#

using PowderCoating.Application.DTOs.Company;
namespace PowderCoating.Application.Interfaces;
/// <summary>
/// Manages the community formula library: sharing, unsharing, importing, and browsing.
/// </summary>
public interface IFormulaLibraryService
{
/// <summary>
/// Returns all published library entries, with AlreadyImported populated for the given company.
/// Optionally filters by search term, output mode, or industry hint.
/// </summary>
Task<IEnumerable<FormulaLibraryCardDto>> BrowseAsync(
int companyId,
string? search = null,
string? outputMode = null,
string? industryHint = null);
/// <summary>Full detail for the import preview modal, including field list and formula.</summary>
Task<FormulaLibraryDetailDto?> GetDetailAsync(int libraryItemId, int companyId);
/// <summary>
/// Publishes a company template to the community library.
/// If the template was previously shared and unpublished, re-publishes the existing row.
/// Updates the library entry fields from the current template state on re-share.
/// </summary>
Task<int> ShareAsync(int companyId, string userId, ShareFormulaRequest request);
/// <summary>Sets IsPublished = false. Existing imports are unaffected.</summary>
Task UnshareAsync(int libraryItemId, int companyId);
/// <summary>
/// Copies a library entry into the company's local CustomItemTemplate table.
/// If the company already has an import record for this entry, returns the existing template id.
/// </summary>
Task<int> ImportAsync(int libraryItemId, int companyId, string userId);
/// <summary>
/// Returns the library status for a given CustomItemTemplate — whether it is shared,
/// eligible to be shared, and where it was imported from if applicable.
/// </summary>
Task<FormulaLibraryStatusDto> GetTemplateLibraryStatusAsync(int templateId, int companyId);
/// <summary>
/// Nulls out DiagramImagePath on the FormulaLibraryItem and all imported copies
/// when a source template's diagram is removed. Call from CompanySettingsController
/// when a diagram is deleted or replaced.
/// </summary>
Task CascadeRemoveDiagramAsync(int sourceCustomItemTemplateId);
/// <summary>
/// Records or toggles a thumbs-up/down vote from the given company.
/// If the same vote already exists it is removed (toggle off).
/// If the opposite vote exists it is replaced.
/// Companies cannot rate their own formulas.
/// Returns the updated counts for the library entry.
/// </summary>
Task<(int ThumbsUp, int ThumbsDown, bool? MyVote)> RateAsync(
int libraryItemId, int companyId, bool isPositive);
}