Update profit-loss

This commit is contained in:
2026-05-26 14:59:56 +07:00
parent b8be29e110
commit 024d9ee637
10 changed files with 354 additions and 421 deletions
+35 -60
View File
@@ -427,93 +427,68 @@ func DashboardAnalyticsModelToContract(resp *models.DashboardAnalyticsResponse)
}
}
// ProfitLossAnalyticsContractToModel transforms contract request to model
func ProfitLossAnalyticsContractToModel(req *contract.ProfitLossAnalyticsRequest) (*models.ProfitLossAnalyticsRequest, error) {
if req == nil {
return nil, fmt.Errorf("request cannot be nil")
}
// Parse date range using utility function
dateFrom, dateTo, err := util.ParseDateRangeToJakartaTime(req.DateFrom, req.DateTo)
dateTime, err := util.ParseDateToJakartaTime(req.Date)
if err != nil {
return nil, fmt.Errorf("invalid date format: %w", err)
}
if dateFrom == nil || dateTo == nil {
return nil, fmt.Errorf("both date_from and date_to are required")
if dateTime == nil {
return nil, fmt.Errorf("date is required")
}
return &models.ProfitLossAnalyticsRequest{
OrganizationID: req.OrganizationID,
OutletID: parseOutletID(req.OutletID),
DateFrom: *dateFrom,
DateTo: *dateTo,
GroupBy: req.GroupBy,
Date: *dateTime,
}, nil
}
// ProfitLossAnalyticsModelToContract transforms model response to contract
func ProfitLossAnalyticsModelToContract(resp *models.ProfitLossAnalyticsResponse) *contract.ProfitLossAnalyticsResponse {
if resp == nil {
return nil
}
// Transform profit/loss data
data := make([]contract.ProfitLossData, len(resp.Data))
for i, item := range resp.Data {
data[i] = contract.ProfitLossData{
Date: item.Date,
Revenue: item.Revenue,
Cost: item.Cost,
GrossProfit: item.GrossProfit,
GrossProfitMargin: item.GrossProfitMargin,
Tax: item.Tax,
Discount: item.Discount,
NetProfit: item.NetProfit,
NetProfitMargin: item.NetProfitMargin,
Orders: item.Orders,
}
mainSummary := make([]contract.ProfitLossSummaryRow, len(resp.MainSummary))
for i, row := range resp.MainSummary {
mainSummary[i] = profitLossSummaryRowModelToContract(row)
}
// Transform product profit data
productData := make([]contract.ProductProfitData, len(resp.ProductData))
for i, item := range resp.ProductData {
productData[i] = contract.ProductProfitData{
ProductID: item.ProductID,
ProductName: item.ProductName,
CategoryID: item.CategoryID,
CategoryName: item.CategoryName,
QuantitySold: item.QuantitySold,
Revenue: item.Revenue,
Cost: item.Cost,
GrossProfit: item.GrossProfit,
GrossProfitMargin: item.GrossProfitMargin,
AveragePrice: item.AveragePrice,
AverageCost: item.AverageCost,
ProfitPerUnit: item.ProfitPerUnit,
opsItems := make([]contract.OperationalExpenseItem, len(resp.OperationalExpenses))
for i, item := range resp.OperationalExpenses {
opsItems[i] = contract.OperationalExpenseItem{
Item: item.Item,
Nominal: item.Nominal,
}
}
return &contract.ProfitLossAnalyticsResponse{
OrganizationID: resp.OrganizationID,
OutletID: resp.OutletID,
DateFrom: resp.DateFrom,
DateTo: resp.DateTo,
GroupBy: resp.GroupBy,
Summary: contract.ProfitLossSummary{
TotalRevenue: resp.Summary.TotalRevenue,
TotalCost: resp.Summary.TotalCost,
GrossProfit: resp.Summary.GrossProfit,
GrossProfitMargin: resp.Summary.GrossProfitMargin,
TotalTax: resp.Summary.TotalTax,
TotalDiscount: resp.Summary.TotalDiscount,
NetProfit: resp.Summary.NetProfit,
NetProfitMargin: resp.Summary.NetProfitMargin,
TotalOrders: resp.Summary.TotalOrders,
AverageProfit: resp.Summary.AverageProfit,
ProfitabilityRatio: resp.Summary.ProfitabilityRatio,
},
Data: data,
ProductData: productData,
OrganizationID: resp.OrganizationID,
OutletID: resp.OutletID,
Date: resp.Date,
MainSummary: mainSummary,
OperationalExpenses: opsItems,
OperationalExpensesTotal: resp.OperationalExpensesTotal,
}
}
func profitLossSummaryRowModelToContract(row models.ProfitLossSummaryRow) contract.ProfitLossSummaryRow {
subItems := make([]contract.ProfitLossSummaryRow, len(row.SubItems))
for i, sub := range row.SubItems {
subItems[i] = profitLossSummaryRowModelToContract(sub)
}
return contract.ProfitLossSummaryRow{
ID: row.ID,
Label: row.Label,
IsBold: row.IsBold,
TodayNominal: row.TodayNominal,
TodayPct: row.TodayPct,
MtdNominal: row.MtdNominal,
MtdPct: row.MtdPct,
SubItems: subItems,
}
}