initial commit

This commit is contained in:
2026-07-21 14:41:46 +07:00
commit 1bfa3dd1c2
1159 changed files with 88228 additions and 0 deletions
+20
View File
@@ -0,0 +1,20 @@
using FluentValidation;
namespace Indotalent.Shared.Utils;
public static class FluentValidationHelper
{
public static Func<object, string, Task<IEnumerable<string>>> ValidateValue<T>(this AbstractValidator<T> validator) => async (model, propertyName) =>
{
if (model is not T typedModel)
return Array.Empty<string>();
var context = ValidationContext<T>.CreateWithOptions(typedModel, x => x.IncludeProperties(propertyName));
var result = await validator.ValidateAsync(context);
if (result.IsValid)
return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage);
};
}
+126
View File
@@ -0,0 +1,126 @@
using Indotalent.Data.Entities;
using Indotalent.Data.Enums;
using Indotalent.Infrastructure.Database;
using Microsoft.EntityFrameworkCore;
namespace Indotalent.Shared.Utils;
public static class InventoryTransactionHelper
{
public static void CalculateInvenTrans(AppDbContext context, InventoryTransaction transaction)
{
if (transaction == null)
{
throw new Exception("Inventory transaction is null");
}
var moduleName = transaction.ModuleName;
if (moduleName != "StockCount" && (transaction.Movement ?? 0.0) <= 0.0)
{
throw new Exception("Quantity must not zero and should be positive.");
}
if (moduleName == "StockCount" && (transaction.QtySCCount ?? 0.0) <= 0.0)
{
throw new Exception("Quantity must not zero and should be positive.");
}
switch (moduleName)
{
case "DeliveryOrder":
transaction.TransType = InventoryTransType.Out;
transaction.WarehouseFromId = transaction.WarehouseId;
transaction.WarehouseToId = GetSystemWarehouseId(context, "CUSTOMER");
break;
case "GoodsReceive":
transaction.TransType = InventoryTransType.In;
transaction.WarehouseFromId = GetSystemWarehouseId(context, "VENDOR");
transaction.WarehouseToId = transaction.WarehouseId;
break;
case "SalesReturn":
transaction.TransType = InventoryTransType.In;
transaction.WarehouseFromId = GetSystemWarehouseId(context, "VENDOR");
transaction.WarehouseToId = transaction.WarehouseId;
break;
case "PurchaseReturn":
transaction.TransType = InventoryTransType.Out;
transaction.WarehouseFromId = transaction.WarehouseId;
transaction.WarehouseToId = GetSystemWarehouseId(context, "CUSTOMER");
break;
case "TransferIn":
transaction.TransType = InventoryTransType.In;
transaction.WarehouseFromId = GetSystemWarehouseId(context, "TRANSIT");
transaction.WarehouseToId = transaction.WarehouseId;
break;
case "TransferOut":
transaction.TransType = InventoryTransType.Out;
transaction.WarehouseFromId = transaction.WarehouseId;
transaction.WarehouseToId = GetSystemWarehouseId(context, "TRANSIT");
break;
case "StockCount":
transaction.QtySCSys = GetStock(context, transaction.WarehouseId, transaction.ProductId, transaction.Id);
transaction.QtySCDelta = transaction.QtySCSys - transaction.QtySCCount;
transaction.Movement = Math.Abs(transaction.QtySCDelta ?? 0.0);
if (transaction.QtySCDelta < 0.0)
{
transaction.TransType = InventoryTransType.In;
transaction.WarehouseFromId = GetSystemWarehouseId(context, "STOCK_COUNT");
transaction.WarehouseToId = transaction.WarehouseId;
}
else
{
transaction.TransType = InventoryTransType.Out;
transaction.WarehouseFromId = transaction.WarehouseId;
transaction.WarehouseToId = GetSystemWarehouseId(context, "STOCK_COUNT");
}
break;
case "NegativeAdjustment":
transaction.TransType = InventoryTransType.Out;
transaction.WarehouseFromId = transaction.WarehouseId;
transaction.WarehouseToId = GetSystemWarehouseId(context, "ADJUSTMENT");
break;
case "PositiveAdjustment":
transaction.TransType = InventoryTransType.In;
transaction.WarehouseFromId = GetSystemWarehouseId(context, "ADJUSTMENT");
transaction.WarehouseToId = transaction.WarehouseId;
break;
case "Scrapping":
transaction.TransType = InventoryTransType.Out;
transaction.WarehouseFromId = transaction.WarehouseId;
transaction.WarehouseToId = GetSystemWarehouseId(context, "SCRAPPING");
break;
}
transaction.Stock = (transaction.Movement ?? 0.0) * (int)(transaction.TransType ?? InventoryTransType.In);
}
public static double GetStock(AppDbContext context, string? warehouseId, string? productId, string? currentId = null)
{
return context.InventoryTransaction
.Where(x =>
x.Status == InventoryTransactionStatus.Confirmed &&
x.WarehouseId == warehouseId &&
x.ProductId == productId &&
x.Id != currentId)
.Sum(x => x.Stock ?? 0.0);
}
private static string? GetSystemWarehouseId(AppDbContext context, string name)
{
return context.Warehouse
.Where(x => x.SystemWarehouse == true && x.Name == name)
.Select(x => x.Id)
.FirstOrDefault();
}
}
+32
View File
@@ -0,0 +1,32 @@
using Indotalent.Data.Entities;
using Indotalent.Infrastructure.Database;
using Microsoft.EntityFrameworkCore;
namespace Indotalent.Shared.Utils;
public static class PurchaseOrderHelper
{
public static void Recalculate(AppDbContext context, string purchaseOrderId)
{
var purchaseOrder = context.PurchaseOrder
.Include(x => x.Tax)
.SingleOrDefault(x => x.Id == purchaseOrderId);
if (purchaseOrder == null)
return;
var purchaseOrderItems = context.PurchaseOrderItem
.Where(x => x.PurchaseOrderId == purchaseOrderId)
.ToList();
purchaseOrder.BeforeTaxAmount = purchaseOrderItems.Sum(x => (x.UnitPrice ?? 0) * (decimal)(x.Quantity ?? 0));
var taxPercentage = purchaseOrder.Tax?.PercentageValue ?? 0;
purchaseOrder.TaxAmount = (purchaseOrder.BeforeTaxAmount ?? 0) * taxPercentage / 100;
purchaseOrder.AfterTaxAmount = (purchaseOrder.BeforeTaxAmount ?? 0) + (purchaseOrder.TaxAmount ?? 0);
context.PurchaseOrder.Update(purchaseOrder);
context.SaveChanges();
}
}
+31
View File
@@ -0,0 +1,31 @@
using Indotalent.Data.Entities;
using Indotalent.Infrastructure.Database;
using Microsoft.EntityFrameworkCore;
namespace Indotalent.Shared.Utils;
public static class PurchaseRequisitionHelper
{
public static void Recalculate(AppDbContext context, string requisitionId)
{
var requisition = context.PurchaseRequisition
.Include(x => x.Tax)
.SingleOrDefault(x => x.Id == requisitionId);
if (requisition == null) return;
var items = context.PurchaseRequisitionItem
.Where(x => x.PurchaseRequisitionId == requisitionId)
.ToList();
requisition.BeforeTaxAmount = items.Sum(x => (x.UnitPrice ?? 0m) * (decimal)(x.Quantity ?? 0.0));
var taxPercentage = requisition.Tax?.PercentageValue ?? 0;
requisition.TaxAmount = (requisition.BeforeTaxAmount ?? 0m) * (decimal)taxPercentage / 100m;
requisition.AfterTaxAmount = (requisition.BeforeTaxAmount ?? 0m) + (requisition.TaxAmount ?? 0m);
context.PurchaseRequisition.Update(requisition);
context.SaveChanges();
}
}
+32
View File
@@ -0,0 +1,32 @@
using Indotalent.Data.Entities;
using Indotalent.Infrastructure.Database;
using Microsoft.EntityFrameworkCore;
namespace Indotalent.Shared.Utils;
public static class SalesOrderHelper
{
public static void Recalculate(AppDbContext context, string salesOrderId)
{
var salesOrder = context.SalesOrder
.Include(x => x.Tax)
.SingleOrDefault(x => x.Id == salesOrderId);
if (salesOrder == null)
return;
var salesOrderItems = context.SalesOrderItem
.Where(x => x.SalesOrderId == salesOrderId)
.ToList();
salesOrder.BeforeTaxAmount = salesOrderItems.Sum(x => x.Total ?? 0m);
var taxPercentage = salesOrder.Tax?.PercentageValue ?? 0;
salesOrder.TaxAmount = (salesOrder.BeforeTaxAmount ?? 0m) * (decimal)taxPercentage / 100m;
salesOrder.AfterTaxAmount = (salesOrder.BeforeTaxAmount ?? 0m) + (salesOrder.TaxAmount ?? 0m);
context.SalesOrder.Update(salesOrder);
context.SaveChanges();
}
}
+31
View File
@@ -0,0 +1,31 @@
using Indotalent.Data.Entities;
using Indotalent.Infrastructure.Database;
using Microsoft.EntityFrameworkCore;
namespace Indotalent.Shared.Utils;
public static class SalesQuotationHelper
{
public static void Recalculate(AppDbContext context, string quotationId)
{
var quotation = context.SalesQuotation
.Include(x => x.Tax)
.SingleOrDefault(x => x.Id == quotationId);
if (quotation == null) return;
var items = context.SalesQuotationItem
.Where(x => x.SalesQuotationId == quotationId)
.ToList();
quotation.BeforeTaxAmount = items.Sum(x => (x.UnitPrice ?? 0m) * (decimal)(x.Quantity ?? 0.0));
var taxPercentage = quotation.Tax?.PercentageValue ?? 0;
quotation.TaxAmount = (quotation.BeforeTaxAmount ?? 0m) * (decimal)taxPercentage / 100m;
quotation.AfterTaxAmount = (quotation.BeforeTaxAmount ?? 0m) + (quotation.TaxAmount ?? 0m);
context.SalesQuotation.Update(quotation);
context.SaveChanges();
}
}
+25
View File
@@ -0,0 +1,25 @@
namespace Indotalent.Shared.Utils;
public static class SequentialGuidGenerator
{
public static string NewSequentialId()
{
byte[] guidBytes = Guid.NewGuid().ToByteArray();
byte[] timestampBytes = BitConverter.GetBytes(DateTime.UtcNow.Ticks);
if (BitConverter.IsLittleEndian)
{
Array.Reverse(timestampBytes);
}
guidBytes[10] = timestampBytes[2];
guidBytes[11] = timestampBytes[3];
guidBytes[12] = timestampBytes[4];
guidBytes[13] = timestampBytes[5];
guidBytes[14] = timestampBytes[6];
guidBytes[15] = timestampBytes[7];
return new Guid(guidBytes).ToString();
}
}