case 3994
This commit is contained in:
@@ -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.
|
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
|
### Quotes
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,20 @@ namespace AyaNova.DataList
|
|||||||
public CustomerDataList()
|
public CustomerDataList()
|
||||||
{
|
{
|
||||||
DefaultListAType = AyaType.Customer;
|
DefaultListAType = AyaType.Customer;
|
||||||
SQLFrom = "from acustomer left join aheadoffice on (acustomer.headofficeid=aheadoffice.id) left join acontract on (acustomer.contractid=acontract.id)";
|
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);
|
var RoleSet = BizRoles.GetRoleSet(DefaultListAType);
|
||||||
AllowedRoles = RoleSet.ReadFullRecord | RoleSet.Change;
|
AllowedRoles = RoleSet.ReadFullRecord | RoleSet.Change;
|
||||||
DefaultColumns = new List<string>() { "customername", "customerphone1", "customeremail", "customerheadoffice" };
|
DefaultColumns = new List<string>() { "customername", "customerphone1", "customeremail", "customerheadoffice" };
|
||||||
@@ -18,6 +31,25 @@ namespace AyaNova.DataList
|
|||||||
|
|
||||||
FieldDefinitions = new List<DataListFieldDefinition>();
|
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
|
FieldDefinitions.Add(new DataListFieldDefinition
|
||||||
{
|
{
|
||||||
TKey = "CustomerName",
|
TKey = "CustomerName",
|
||||||
|
|||||||
@@ -10,13 +10,26 @@ namespace AyaNova.DataList
|
|||||||
public UnitDataList()
|
public UnitDataList()
|
||||||
{
|
{
|
||||||
DefaultListAType = AyaType.Unit;
|
DefaultListAType = AyaType.Unit;
|
||||||
SQLFrom = "from aunit as amainunit "
|
SQLFrom = @"FROM AUNIT AS AMAINUNIT
|
||||||
+ "left join acustomer on (amainunit.customerid=acustomer.id) "
|
LEFT JOIN ACUSTOMER ON (AMAINUNIT.CUSTOMERID = ACUSTOMER.ID)
|
||||||
+ "left join aunit as aparentunit on (amainunit.parentunitid=aparentunit.id) "
|
LEFT JOIN AUNIT AS APARENTUNIT ON (AMAINUNIT.PARENTUNITID = APARENTUNIT.ID)
|
||||||
+ "left join aunitmodel on (amainunit.unitmodelid=aunitmodel.id) "
|
LEFT JOIN AUNITMODEL ON (AMAINUNIT.UNITMODELID = AUNITMODEL.ID)
|
||||||
+ "left join avendor on (amainunit.purchasedfromvendorid=avendor.id) "
|
LEFT JOIN AVENDOR ON (AMAINUNIT.PURCHASEDFROMVENDORID = AVENDOR.ID)
|
||||||
+ "left join aunit as areplacedbyunit on (amainunit.replacedbyunitid=areplacedbyunit.id) "
|
LEFT JOIN AUNIT AS AREPLACEDBYUNIT ON (AMAINUNIT.REPLACEDBYUNITID = AREPLACEDBYUNIT.ID)
|
||||||
+ "left join acontract on (amainunit.contractid=acontract.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);
|
var RoleSet = BizRoles.GetRoleSet(DefaultListAType);
|
||||||
AllowedRoles = RoleSet.ReadFullRecord | RoleSet.Change;
|
AllowedRoles = RoleSet.ReadFullRecord | RoleSet.Change;
|
||||||
@@ -24,6 +37,26 @@ namespace AyaNova.DataList
|
|||||||
DefaultSortBy = new Dictionary<string, string>() { { "UnitSerial", "+" } };
|
DefaultSortBy = new Dictionary<string, string>() { { "UnitSerial", "+" } };
|
||||||
FieldDefinitions = new List<DataListFieldDefinition>();
|
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
|
FieldDefinitions.Add(new DataListFieldDefinition
|
||||||
{
|
{
|
||||||
TKey = "UnitSerial",
|
TKey = "UnitSerial",
|
||||||
|
|||||||
@@ -373,6 +373,40 @@ namespace AyaNova.Biz
|
|||||||
o.HeadOfficeViz = await ct.HeadOffice.AsNoTracking().Where(x => x.Id == o.HeadOfficeId).Select(x => x.Name).FirstOrDefaultAsync();
|
o.HeadOfficeViz = await ct.HeadOffice.AsNoTracking().Where(x => x.Id == o.HeadOfficeId).Select(x => x.Name).FirstOrDefaultAsync();
|
||||||
if (o.ContractId != null)
|
if (o.ContractId != null)
|
||||||
o.ContractViz = await ct.Contract.AsNoTracking().Where(x => x.Id == o.ContractId).Select(x => x.Name).FirstOrDefaultAsync();
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@@ -39,7 +39,10 @@ namespace AyaNova.Models
|
|||||||
[NotMapped]
|
[NotMapped]
|
||||||
public string ContractViz { get; set; }
|
public string ContractViz { get; set; }
|
||||||
public DateTime? ContractExpires { 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 Phone1 { get; set; }
|
||||||
public string Phone2 { get; set; }
|
public string Phone2 { get; set; }
|
||||||
public string Phone3 { get; set; }
|
public string Phone3 { get; set; }
|
||||||
|
|||||||
@@ -58,6 +58,12 @@ namespace AyaNova.Models
|
|||||||
public long LastMeterViz { get; set; }
|
public long LastMeterViz { get; set; }
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
public DateTime? LastMeterDateViz { get; set; }
|
public DateTime? LastMeterDateViz { get; set; }
|
||||||
|
|
||||||
|
[NotMapped]
|
||||||
|
public long? LastCompletedWorkOrderViz { get; set; }
|
||||||
|
[NotMapped]
|
||||||
|
public DateTime? LastCompletedServiceDateViz { get; set; }
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
public string LastMeterNotesViz { get; set; }
|
public string LastMeterNotesViz { get; set; }
|
||||||
public bool LifeTimeWarranty { get; set; }
|
public bool LifeTimeWarranty { get; set; }
|
||||||
|
|||||||
@@ -2288,5 +2288,7 @@
|
|||||||
"ScheduleWOColorFrom":"Farbquelle für Arbeitsauftrag",
|
"ScheduleWOColorFrom":"Farbquelle für Arbeitsauftrag",
|
||||||
"NoColor":"Keine Farbe",
|
"NoColor":"Keine Farbe",
|
||||||
"ScheduleOptions":"Zeitplaneinstellungen",
|
"ScheduleOptions":"Zeitplaneinstellungen",
|
||||||
"ScheduleShowTypes":"Elemente zum Anzeigen"
|
"ScheduleShowTypes":"Elemente zum Anzeigen",
|
||||||
|
"LastCompletedWorkOrder":"Letzter abgeschlossener Arbeitsauftrag",
|
||||||
|
"LastCompletedWorkOrderServiceDate":"Letzter abgeschlossener Servicetermin"
|
||||||
}
|
}
|
||||||
@@ -2288,7 +2288,9 @@
|
|||||||
"ScheduleWOColorFrom":"Work order color source",
|
"ScheduleWOColorFrom":"Work order color source",
|
||||||
"NoColor":"No color",
|
"NoColor":"No color",
|
||||||
"ScheduleOptions":"Schedule settings",
|
"ScheduleOptions":"Schedule settings",
|
||||||
"ScheduleShowTypes":"Show"
|
"ScheduleShowTypes":"Show",
|
||||||
|
"LastCompletedWorkOrder":"Last completed work order",
|
||||||
|
"LastCompletedWorkOrderServiceDate":"Last completed service date"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2288,5 +2288,7 @@
|
|||||||
"ScheduleWOColorFrom":"Fuente de color de la orden de trabajo",
|
"ScheduleWOColorFrom":"Fuente de color de la orden de trabajo",
|
||||||
"NoColor":"Sin color",
|
"NoColor":"Sin color",
|
||||||
"ScheduleOptions":"Configuración de programación",
|
"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"
|
||||||
}
|
}
|
||||||
@@ -2288,5 +2288,7 @@
|
|||||||
"ScheduleWOColorFrom":"Source de couleur de l'ordre de travail",
|
"ScheduleWOColorFrom":"Source de couleur de l'ordre de travail",
|
||||||
"NoColor":"Sans couleur",
|
"NoColor":"Sans couleur",
|
||||||
"ScheduleOptions":"Paramètres de planification",
|
"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é"
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user