case 3994

This commit is contained in:
2021-09-30 20:24:48 +00:00
parent 772a47842f
commit 18c9d2e7d4
11 changed files with 175 additions and 16 deletions

View File

@@ -127,6 +127,10 @@ Tasks have been changed to a collection stored *with* the work order rather than
Pricing and costs are now clearly displayed on the work order in a consistent manner between all billable items that have prices. List price and final price are both shown so that it's clear that a contract or manual override have affected the final price. Most non management roles will not see costs or prices by default. Most prices (except for Parts which tend to have volatile pricing) are not stored with the work order but instead calculated on the fly when a work order is opened / printed. This is part of the decoupling process that allows for easily changing the Contract or Customer on an existing Work order. This means that similar to v7 some items like taxes and rates cannot be changed once they have been used on a work order however Parts are an exception as the pricing is considered more volatile so part prices are "snapshotted" on being added to a work order.
#### Customer and Unit data list "Last completed... " columns
In v7 the Clients grid and the Units grid show the "Last closed service workorder" and "Last closed service date" columns.
In v8 since Closed is now a propert of the work order status the Customer and Unit data tables will show "Last completed work order" as "Last completed service date" instead.
### Quotes

View File

@@ -9,8 +9,21 @@ namespace AyaNova.DataList
{
public CustomerDataList()
{
DefaultListAType = AyaType.Customer;
SQLFrom = "from acustomer left join aheadoffice on (acustomer.headofficeid=aheadoffice.id) left join acontract on (acustomer.contractid=acontract.id)";
DefaultListAType = AyaType.Customer;
SQLFrom = @"FROM ACUSTOMER
LEFT JOIN AHEADOFFICE ON (ACUSTOMER.HEADOFFICEID = AHEADOFFICE.ID)
LEFT JOIN ACONTRACT ON (ACUSTOMER.CONTRACTID = ACONTRACT.ID)
LEFT JOIN LATERAL
(SELECT serial AS LASTWORKORDERSERIAL,
SERVICEDATE AS LASTWORKORDERSERVICEDATE,
AWORKORDER.ID AS LASTWORKORDERID
FROM AWORKORDER
LEFT JOIN AWORKORDERSTATUS ON AWORKORDER.LASTSTATUSID = AWORKORDERSTATUS.ID
WHERE AWORKORDERSTATUS.COMPLETED = TRUE
AND AWORKORDER.CUSTOMERID = ACUSTOMER.ID
ORDER BY AWORKORDER.ID DESC
LIMIT 1) AS LWO ON TRUE";
var RoleSet = BizRoles.GetRoleSet(DefaultListAType);
AllowedRoles = RoleSet.ReadFullRecord | RoleSet.Change;
DefaultColumns = new List<string>() { "customername", "customerphone1", "customeremail", "customerheadoffice" };
@@ -18,6 +31,25 @@ namespace AyaNova.DataList
FieldDefinitions = new List<DataListFieldDefinition>();
FieldDefinitions.Add(new DataListFieldDefinition
{
FieldKey = "LastCompletedWorkOrder",
TKey = "LastCompletedWorkOrder",
AType = (int)AyaType.WorkOrder,
UiFieldDataType = (int)UiFieldDataType.Integer,
SqlIdColumnName = "lwo.LASTWORKORDERID",
SqlValueColumnName = "lwo.lastworkorderserial"
});
FieldDefinitions.Add(new DataListFieldDefinition
{
TKey = "LastCompletedWorkOrderServiceDate",
FieldKey = "LastCompletedWorkOrderServiceDate",
UiFieldDataType = (int)UiFieldDataType.DateTime,
SqlValueColumnName = "lwo.lastworkorderservicedate"
});
FieldDefinitions.Add(new DataListFieldDefinition
{
TKey = "CustomerName",

View File

@@ -9,21 +9,54 @@ namespace AyaNova.DataList
{
public UnitDataList()
{
DefaultListAType = AyaType.Unit;
SQLFrom = "from aunit as amainunit "
+ "left join acustomer on (amainunit.customerid=acustomer.id) "
+ "left join aunit as aparentunit on (amainunit.parentunitid=aparentunit.id) "
+ "left join aunitmodel on (amainunit.unitmodelid=aunitmodel.id) "
+ "left join avendor on (amainunit.purchasedfromvendorid=avendor.id) "
+ "left join aunit as areplacedbyunit on (amainunit.replacedbyunitid=areplacedbyunit.id) "
+ "left join acontract on (amainunit.contractid=acontract.id)";
DefaultListAType = AyaType.Unit;
SQLFrom = @"FROM AUNIT AS AMAINUNIT
LEFT JOIN ACUSTOMER ON (AMAINUNIT.CUSTOMERID = ACUSTOMER.ID)
LEFT JOIN AUNIT AS APARENTUNIT ON (AMAINUNIT.PARENTUNITID = APARENTUNIT.ID)
LEFT JOIN AUNITMODEL ON (AMAINUNIT.UNITMODELID = AUNITMODEL.ID)
LEFT JOIN AVENDOR ON (AMAINUNIT.PURCHASEDFROMVENDORID = AVENDOR.ID)
LEFT JOIN AUNIT AS AREPLACEDBYUNIT ON (AMAINUNIT.REPLACEDBYUNITID = AREPLACEDBYUNIT.ID)
LEFT JOIN ACONTRACT ON (AMAINUNIT.CONTRACTID = ACONTRACT.ID)
LEFT JOIN LATERAL
(SELECT serial AS LASTWORKORDERSERIAL,
SERVICEDATE AS LASTWORKORDERSERVICEDATE,
AWORKORDERITEMUNIT.ID AS LASTWORKORDERITEMUNITID
FROM AWORKORDER
LEFT JOIN AWORKORDERITEM ON AWORKORDER.ID = AWORKORDERITEM.WORKORDERID
LEFT JOIN AWORKORDERSTATUS ON AWORKORDER.LASTSTATUSID = AWORKORDERSTATUS.ID
LEFT JOIN AWORKORDERITEMUNIT ON AWORKORDERITEM.ID = AWORKORDERITEMUNIT.WORKORDERITEMID
WHERE AWORKORDERITEMUNIT.ID = AMAINUNIT.ID
AND AWORKORDERSTATUS.COMPLETED = TRUE
ORDER BY AWORKORDER.ID DESC
LIMIT 1) AS LWO ON TRUE";
var RoleSet = BizRoles.GetRoleSet(DefaultListAType);
AllowedRoles = RoleSet.ReadFullRecord | RoleSet.Change;
DefaultColumns = new List<string>() { "UnitSerial", "UnitModel", "Customer", "Active" };
DefaultSortBy = new Dictionary<string, string>() { { "UnitSerial", "+" } };
FieldDefinitions = new List<DataListFieldDefinition>();
FieldDefinitions.Add(new DataListFieldDefinition
{
FieldKey = "LastCompletedWorkOrder",
TKey = "LastCompletedWorkOrder",
AType = (int)AyaType.WorkOrderItemUnit,
UiFieldDataType = (int)UiFieldDataType.Integer,
SqlIdColumnName = "lwo.lastworkorderitemunitid",
SqlValueColumnName = "lwo.lastworkorderserial"
});
FieldDefinitions.Add(new DataListFieldDefinition
{
TKey = "LastCompletedWorkOrderServiceDate",
FieldKey = "LastCompletedWorkOrderServiceDate",
UiFieldDataType = (int)UiFieldDataType.DateTime,
SqlValueColumnName = "lwo.lastworkorderservicedate"
});
FieldDefinitions.Add(new DataListFieldDefinition
{
TKey = "UnitSerial",

View File

@@ -373,6 +373,40 @@ namespace AyaNova.Biz
o.HeadOfficeViz = await ct.HeadOffice.AsNoTracking().Where(x => x.Id == o.HeadOfficeId).Select(x => x.Name).FirstOrDefaultAsync();
if (o.ContractId != null)
o.ContractViz = await ct.Contract.AsNoTracking().Where(x => x.Id == o.ContractId).Select(x => x.Name).FirstOrDefaultAsync();
/*
last completed work order stuff, way to complex to fetch via EF Core so dropping to raw sql
SELECT serial AS LASTWORKORDERSERIAL,
SERVICEDATE AS LASTWORKORDERSERVICEDATE,
AWORKORDER.ID AS LASTWORKORDERID
FROM AWORKORDER
LEFT JOIN AWORKORDERSTATUS ON AWORKORDER.LASTSTATUSID = AWORKORDERSTATUS.ID
WHERE AWORKORDERSTATUS.COMPLETED = TRUE
AND AWORKORDER.CUSTOMERID = ACUSTOMER.ID
ORDER BY AWORKORDER.ID DESC
LIMIT 1
*/
using (var command = ct.Database.GetDbConnection().CreateCommand())
{
await ct.Database.OpenConnectionAsync();
command.CommandText = @$"SELECT serial AS LASTWORKORDERSERIAL,
SERVICEDATE AS LASTWORKORDERSERVICEDATE
FROM AWORKORDER
LEFT JOIN AWORKORDERSTATUS ON AWORKORDER.LASTSTATUSID = AWORKORDERSTATUS.ID
WHERE AWORKORDERSTATUS.COMPLETED = TRUE
AND AWORKORDER.CUSTOMERID = {o.Id}
ORDER BY AWORKORDER.ID DESC
LIMIT 1";
using (var dr = await command.ExecuteReaderAsync())
if (await dr.ReadAsync())
{
o.LastCompletedWorkOrderViz = dr.GetInt64(0);
o.LastCompletedServiceDateViz = dr.GetDateTime(1);
}
await ct.Database.CloseConnectionAsync();
}
}

View File

@@ -308,6 +308,45 @@ namespace AyaNova.Biz
}
}
/*
last completed work order stuff, way to complex to fetch via EF Core so dropping to raw sql
SELECT serial AS LASTWORKORDERSERIAL,
SERVICEDATE AS LASTWORKORDERSERVICEDATE,
AWORKORDERITEMUNIT.UNITID AS LASTWORKORDERUNITID,
AWORKORDERITEMUNIT.ID AS LASTWORKORDERITEMUNITID
FROM AWORKORDER
LEFT JOIN AWORKORDERITEM ON AWORKORDER.ID = AWORKORDERITEM.WORKORDERID
LEFT JOIN AWORKORDERSTATUS ON AWORKORDER.LASTSTATUSID = AWORKORDERSTATUS.ID
LEFT JOIN AWORKORDERITEMUNIT ON AWORKORDERITEM.ID = AWORKORDERITEMUNIT.WORKORDERITEMID
WHERE AWORKORDERITEMUNIT.ID = AMAINUNIT.ID
AND AWORKORDERSTATUS.COMPLETED = TRUE
ORDER BY AWORKORDER.ID DESC
LIMIT 1
*/
using (var command = ct.Database.GetDbConnection().CreateCommand())
{
await ct.Database.OpenConnectionAsync();
command.CommandText = @$"SELECT serial AS LASTWORKORDERSERIAL,
SERVICEDATE AS LASTWORKORDERSERVICEDATE
FROM AWORKORDER
LEFT JOIN AWORKORDERITEM ON AWORKORDER.ID = AWORKORDERITEM.WORKORDERID
LEFT JOIN AWORKORDERSTATUS ON AWORKORDER.LASTSTATUSID = AWORKORDERSTATUS.ID
LEFT JOIN AWORKORDERITEMUNIT ON AWORKORDERITEM.ID = AWORKORDERITEMUNIT.WORKORDERITEMID
WHERE AWORKORDERITEMUNIT.ID = {o.Id}
AND AWORKORDERSTATUS.COMPLETED = TRUE
ORDER BY AWORKORDER.ID DESC
LIMIT 1";
using (var dr = await command.ExecuteReaderAsync())
if (await dr.ReadAsync())
{
o.LastCompletedWorkOrderViz = dr.GetInt64(0);
o.LastCompletedServiceDateViz = dr.GetDateTime(1);
}
await ct.Database.CloseConnectionAsync();
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
@@ -558,7 +597,7 @@ namespace AyaNova.Biz
}
}
}//Contract expiry event
}

View File

@@ -39,7 +39,10 @@ namespace AyaNova.Models
[NotMapped]
public string ContractViz { get; set; }
public DateTime? ContractExpires { get; set; }
//public long? DefaultServiceTemplateId { get; set; }
[NotMapped]
public long? LastCompletedWorkOrderViz { get; set; }
[NotMapped]
public DateTime? LastCompletedServiceDateViz { get; set; }
public string Phone1 { get; set; }
public string Phone2 { get; set; }
public string Phone3 { get; set; }

View File

@@ -58,6 +58,12 @@ namespace AyaNova.Models
public long LastMeterViz { get; set; }
[NotMapped]
public DateTime? LastMeterDateViz { get; set; }
[NotMapped]
public long? LastCompletedWorkOrderViz { get; set; }
[NotMapped]
public DateTime? LastCompletedServiceDateViz { get; set; }
[NotMapped]
public string LastMeterNotesViz { get; set; }
public bool LifeTimeWarranty { get; set; }

View File

@@ -2288,5 +2288,7 @@
"ScheduleWOColorFrom":"Farbquelle für Arbeitsauftrag",
"NoColor":"Keine Farbe",
"ScheduleOptions":"Zeitplaneinstellungen",
"ScheduleShowTypes":"Elemente zum Anzeigen"
"ScheduleShowTypes":"Elemente zum Anzeigen",
"LastCompletedWorkOrder":"Letzter abgeschlossener Arbeitsauftrag",
"LastCompletedWorkOrderServiceDate":"Letzter abgeschlossener Servicetermin"
}

View File

@@ -2288,7 +2288,9 @@
"ScheduleWOColorFrom":"Work order color source",
"NoColor":"No color",
"ScheduleOptions":"Schedule settings",
"ScheduleShowTypes":"Show"
"ScheduleShowTypes":"Show",
"LastCompletedWorkOrder":"Last completed work order",
"LastCompletedWorkOrderServiceDate":"Last completed service date"

View File

@@ -2288,5 +2288,7 @@
"ScheduleWOColorFrom":"Fuente de color de la orden de trabajo",
"NoColor":"Sin color",
"ScheduleOptions":"Configuración de programación",
"ScheduleShowTypes":"Elementos para mostrar"
"ScheduleShowTypes":"Elementos para mostrar",
"LastCompletedWorkOrder":"Última orden de trabajo completada",
"LastCompletedWorkOrderServiceDate":"Fecha del último servicio completado"
}

View File

@@ -2288,5 +2288,7 @@
"ScheduleWOColorFrom":"Source de couleur de l'ordre de travail",
"NoColor":"Sans couleur",
"ScheduleOptions":"Paramètres de planification",
"ScheduleShowTypes":"Éléments à afficher"
"ScheduleShowTypes":"Éléments à afficher",
"LastCompletedWorkOrder":"Dernier bon de travail terminé",
"LastCompletedWorkOrderServiceDate":"Date du dernier service terminé"
}