|
@@ -16,6 +16,7 @@ using System.Threading.Tasks;
|
|
|
using System.Windows;
|
|
|
using Microsoft.Win32;
|
|
|
using CsvHelper.TypeConversion;
|
|
|
+using NPOI.SS.Formula.Functions;
|
|
|
|
|
|
namespace PRS.Shared
|
|
|
{
|
|
@@ -283,7 +284,7 @@ public class Module
|
|
|
|
|
|
var firstMovements = model.GetTable<StockMovement>();
|
|
|
var full = model.GetTable<StockMovement>("FullTransactions")
|
|
|
- .ToObjects<StockMovement>();
|
|
|
+ .ToObjects<StockMovement>().GroupBy(x => x.Transaction);
|
|
|
var products = model.GetTable<Product>().ToObjects<Product>()
|
|
|
.ToDictionary(x => x.ID, x => x);
|
|
|
var jobs = model.GetTable<Job>().ToObjects<Job>()
|
|
@@ -291,66 +292,141 @@ public class Module
|
|
|
var batches = model.GetTable<StockMovementBatch>().ToObjects<StockMovementBatch>()
|
|
|
.ToDictionary(x => x.ID, x => x);
|
|
|
|
|
|
- foreach (var movement in full)
|
|
|
+ StockMovementTimberlineDirectCost CreateDirectCost(StockMovement movement)
|
|
|
{
|
|
|
- if (!movement.IsTransfer)
|
|
|
- {
|
|
|
- result.AddSuccess(movement, null);
|
|
|
- continue;
|
|
|
- }
|
|
|
+ var job = jobs[movement.Job.ID];
|
|
|
+ var product = products[movement.Product.ID];
|
|
|
|
|
|
- var batch = batches.GetValueOrDefault(movement.Batch.ID);
|
|
|
- if (batch is not null && batch.Type == StockMovementBatchType.Receipt)
|
|
|
+ var directCost = new StockMovementTimberlineDirectCost
|
|
|
{
|
|
|
- result.AddSuccess(movement, null);
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- IStockMovementTimberlineLine line;
|
|
|
+ Job = job.JobNumber,
|
|
|
+ Extra = "",
|
|
|
+ CostCode = product.CostCentre.Code,
|
|
|
+ Category = "",
|
|
|
+ Units = movement.Units,
|
|
|
+ UnitCost = movement.Cost,
|
|
|
+ // TransactionType = ???
|
|
|
+ };
|
|
|
+ return ModifyLine(directCost, movement);
|
|
|
+ }
|
|
|
+ T ModifyLine<T>(T line, StockMovement movement)
|
|
|
+ where T : IStockMovementTimberlineLine
|
|
|
+ {
|
|
|
var product = products[movement.Product.ID];
|
|
|
- if (movement.Job.ID != Guid.Empty)
|
|
|
- {
|
|
|
- var job = jobs[movement.Job.ID];
|
|
|
- var directCost = new StockMovementTimberlineDirectCost
|
|
|
- {
|
|
|
- Job = job.JobNumber,
|
|
|
- Extra = "",
|
|
|
- CostCode = product.CostCentre.Code,
|
|
|
- Category = "",
|
|
|
- Units = movement.Units,
|
|
|
- UnitCost = movement.Cost,
|
|
|
- // TransactionType = ???
|
|
|
- };
|
|
|
- line = directCost;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- line = new StockMovementTimberlineGL
|
|
|
- {
|
|
|
- };
|
|
|
- }
|
|
|
+ var batch = batches.GetValueOrDefault(movement.Batch.ID);
|
|
|
+
|
|
|
line.TransactionDate = movement.Date;
|
|
|
line.Description = product.Name;
|
|
|
line.Amount = movement.Value;
|
|
|
line.CreditAccount = product.PurchaseGL.Code;
|
|
|
line.BatchType = batch?.Type ?? StockMovementBatchType.Transfer;
|
|
|
+ return line;
|
|
|
+ }
|
|
|
|
|
|
- bool success = true;
|
|
|
- if (line is StockMovementTimberlineDirectCost dc)
|
|
|
- {
|
|
|
- success = ProcessDirectCostLine(model, movement, dc);
|
|
|
- }
|
|
|
- else if (line is StockMovementTimberlineGL gl)
|
|
|
+ foreach (var transaction in full)
|
|
|
+ {
|
|
|
+ var movements = new List<StockMovement>();
|
|
|
+ foreach(var movement in transaction)
|
|
|
{
|
|
|
- success = ProcessGLLine(model, movement, gl);
|
|
|
+ if (!movement.IsTransfer)
|
|
|
+ {
|
|
|
+ // Ignore these ones.
|
|
|
+ result.AddSuccess(movement, null);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ movements.Add(movement);
|
|
|
+ }
|
|
|
}
|
|
|
- if (success)
|
|
|
+
|
|
|
+ if(movements.Count == 1)
|
|
|
{
|
|
|
- result.AddSuccess(movement, line);
|
|
|
+ var mvt = movements[0];
|
|
|
+ var batch = batches.GetValueOrDefault(mvt.Batch.ID);
|
|
|
+ if(batch is null)
|
|
|
+ {
|
|
|
+ // What to do?
|
|
|
+ }
|
|
|
+
|
|
|
+ if(batch?.Type == StockMovementBatchType.Stocktake)
|
|
|
+ {
|
|
|
+ if(mvt.Job.ID == Guid.Empty)
|
|
|
+ {
|
|
|
+ var gl = new StockMovementTimberlineGL { };
|
|
|
+ gl = ModifyLine(gl, mvt);
|
|
|
+ if (ProcessGLLine(model, mvt, gl))
|
|
|
+ {
|
|
|
+ result.AddSuccess(mvt, gl);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ result.AddFailed(mvt, "Failed by script.");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ var dc = CreateDirectCost(mvt);
|
|
|
+ if (ProcessDirectCostLine(model, mvt, dc))
|
|
|
+ {
|
|
|
+ result.AddSuccess(mvt, dc);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ result.AddFailed(mvt, "Failed by script.");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ result.AddSuccess(mvt, null);
|
|
|
+ }
|
|
|
}
|
|
|
- else
|
|
|
+ else if(movements.Count == 2)
|
|
|
{
|
|
|
- result.AddFailed(movement, "Failed by script.");
|
|
|
+ var mvtFrom = movements[0];
|
|
|
+ var mvtTo = movements[1];
|
|
|
+ if(mvtFrom.Job.ID == mvtTo.Job.ID)
|
|
|
+ {
|
|
|
+ // Ignore these ones.
|
|
|
+ result.AddSuccess(mvtFrom, null);
|
|
|
+ result.AddSuccess(mvtTo, null);
|
|
|
+ }
|
|
|
+ else if(mvtFrom.Job.ID == Guid.Empty || mvtTo.Job.ID == Guid.Empty)
|
|
|
+ {
|
|
|
+ var jobMvt = mvtFrom.Job.ID == Guid.Empty ? mvtTo : mvtFrom;
|
|
|
+
|
|
|
+ var directCost = CreateDirectCost(jobMvt);
|
|
|
+ if(ProcessDirectCostLine(model, jobMvt, directCost))
|
|
|
+ {
|
|
|
+ result.AddSuccess(jobMvt, directCost);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ result.AddFailed(jobMvt, "Failed by script.");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ var directCostFrom = CreateDirectCost(mvtFrom);
|
|
|
+ var directCostTo = CreateDirectCost(mvtTo);
|
|
|
+
|
|
|
+ if (ProcessDirectCostLine(model, mvtFrom, directCostFrom))
|
|
|
+ {
|
|
|
+ result.AddSuccess(mvtFrom, directCostFrom);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ result.AddFailed(mvtFrom, "Failed by script.");
|
|
|
+ }
|
|
|
+ if (ProcessDirectCostLine(model, mvtTo, directCostTo))
|
|
|
+ {
|
|
|
+ result.AddSuccess(mvtTo, directCostTo);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ result.AddFailed(mvtTo, "Failed by script.");
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|