264 lines
10 KiB
C#
264 lines
10 KiB
C#
using GraphQL;
|
|
using Newtonsoft.Json.Linq;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Xml.Linq;
|
|
using System.IO;
|
|
using System.Timers;
|
|
using RestSharp;
|
|
|
|
namespace BodyshopPartner.Utils
|
|
{
|
|
public static class PPGMixData
|
|
{
|
|
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
|
|
private static string PpgDataQuery = @"query PPGDataPump($today: timestamptz!, $todayplus5: timestamptz!, $shopid: uuid!) {
|
|
bodyshops_by_pk(id:$shopid) {
|
|
id
|
|
shopname
|
|
imexshopid
|
|
}
|
|
jobs(where: {_or: [{_and: [{scheduled_in: {_lte: $todayplus5}}, {scheduled_in: {_gte: $today}}]}, {inproduction: {_eq: true}}]}) {
|
|
id
|
|
ro_number
|
|
status
|
|
ownr_fn
|
|
ownr_ln
|
|
ownr_co_nm
|
|
v_vin
|
|
v_model_yr
|
|
v_make_desc
|
|
v_model_desc
|
|
v_color
|
|
plate_no
|
|
ins_co_nm
|
|
est_ct_fn
|
|
est_ct_ln
|
|
rate_mapa
|
|
rate_lab
|
|
job_totals
|
|
vehicle{
|
|
v_paint_codes
|
|
}
|
|
labhrs: joblines_aggregate(where: {mod_lbr_ty: {_neq: ""LAR""}, removed: {_eq: false}}) {
|
|
aggregate {
|
|
sum {
|
|
mod_lb_hrs
|
|
}
|
|
}
|
|
}
|
|
larhrs: joblines_aggregate(where: { mod_lbr_ty: { _eq: ""LAR""}, removed: { _eq: false} }) {
|
|
aggregate {
|
|
sum {
|
|
mod_lb_hrs
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
";
|
|
private static Timer MixDataImportTimer = new Timer();
|
|
|
|
|
|
public static void StartMixTimer()
|
|
{
|
|
|
|
MixDataImportTimer.Stop();
|
|
double Interval =0;
|
|
|
|
bool parseSuccesful = double.TryParse(Properties.Settings.Default.PaintScaleImportTimer, out Interval);
|
|
|
|
if (parseSuccesful && Interval > 0)
|
|
{
|
|
logger.Debug("Starting Mix Data Import timer. ", Interval * 1000 * 60);
|
|
MixDataImportTimer.Interval = Interval * 1000*60;
|
|
MixDataImportTimer.Elapsed += MixDataImportTimer_Tick;
|
|
MixDataImportTimer.Start();
|
|
}
|
|
|
|
}
|
|
|
|
public static async Task test()
|
|
{
|
|
logger.Info("Starting MixData import.");
|
|
//Check to make sure that the directory exists.
|
|
Directory.CreateDirectory(Properties.Settings.Default.PaintScaleImportPath);
|
|
Directory.CreateDirectory(Path.Combine(Properties.Settings.Default.PaintScaleImportPath, "archive"));
|
|
|
|
//Check to see if there is a file that exists.
|
|
string[] fileEntries = Directory.GetFiles(Properties.Settings.Default.PaintScaleImportPath);
|
|
foreach (string fileName in fileEntries)
|
|
{
|
|
try
|
|
{
|
|
logger.Debug("Reading file in directory: " + fileName);
|
|
|
|
RestRequest request = new RestRequest("/mixdata/upload", Method.Post);
|
|
request.AddHeader("Authorization", "Bearer " + Utils.Auth.authlink.FirebaseToken);
|
|
request.AddFile("file", fileName);
|
|
|
|
request.AddJsonBody(new { bodyshopid = AppMetaData.ActiveShopId });
|
|
RestResponse _ = await AppMetaData.RestClient.ExecuteAsync(request);
|
|
|
|
if (_.IsSuccessful)
|
|
{
|
|
logger.Info("Successful upload");
|
|
string newPath = Path.Combine(Properties.Settings.Default.PaintScaleImportPath, "archive") + @"\\" + DateTime.Now.Ticks + ".xml";
|
|
File.Move(fileName, newPath);
|
|
}
|
|
else
|
|
{
|
|
logger.Error("Unable to process file " + fileName + ". " + _.ErrorMessage);
|
|
}
|
|
}catch (Exception ex)
|
|
{
|
|
Directory.CreateDirectory(Path.Combine(Properties.Settings.Default.PaintScaleImportPath, "errored"));
|
|
string newPath = Path.Combine(Properties.Settings.Default.PaintScaleImportPath, "errored") + @"\\" + DateTime.Now.Ticks + ".xml";
|
|
File.Move(fileName, newPath);
|
|
logger.Error(ex);
|
|
}
|
|
}
|
|
}
|
|
|
|
public static async void MixDataImportTimer_Tick(object sender, ElapsedEventArgs e)
|
|
{
|
|
logger.Info("Starting MixData import ");
|
|
//Check to make sure that the directory exists.
|
|
Directory.CreateDirectory(Properties.Settings.Default.PaintScaleImportPath);
|
|
Directory.CreateDirectory(Path.Combine(Properties.Settings.Default.PaintScaleImportPath, "archive"));
|
|
|
|
//Check to see if there is a file that exists.
|
|
string[] fileEntries = Directory.GetFiles(Properties.Settings.Default.PaintScaleImportPath);
|
|
foreach (string fileName in fileEntries)
|
|
{
|
|
logger.Debug("Reading file in directory: " + fileName);
|
|
|
|
|
|
|
|
RestRequest request = new RestRequest("/mixdata/upload",Method.Post);
|
|
//Check whether to update the token first.
|
|
await Utils.Auth.Refresh();
|
|
request.AddHeader("Authorization", "Bearer " + Utils.Auth.authlink.FirebaseToken);
|
|
request.AddFile("file", Path.Combine(Properties.Settings.Default.PaintScaleImportPath, fileName));
|
|
|
|
RestResponse _ = await AppMetaData.RestClient.ExecuteAsync(request);
|
|
|
|
if (_.IsSuccessful)
|
|
{
|
|
logger.Info("Successful upload");
|
|
}
|
|
|
|
}
|
|
|
|
//If a file does exist, read it, and send it up to the API with the Active Shop ID & job.
|
|
|
|
//On succesful send, archive the file
|
|
|
|
//Make sure the archive directory exists
|
|
|
|
//Rename and move the file to the archive directory.
|
|
}
|
|
|
|
public static async Task PushDataToPPG()
|
|
{
|
|
try
|
|
{
|
|
//Get the path for the XML file that should be written. Ensure that we can read and write to that directory.
|
|
|
|
//Query the database based on the active shop for all work that's coming within the next 5 days + all active work.
|
|
|
|
var r = new GraphQLRequest
|
|
{
|
|
Query = PpgDataQuery,
|
|
Variables = new
|
|
{
|
|
today = DateTime.Now.Date,
|
|
todayplus5 = DateTime.Now.Date.AddDays(5),
|
|
shopid = AppMetaData.ActiveShopId
|
|
}
|
|
};
|
|
|
|
|
|
var data = await Utils.GraphQL.ExecuteQuery(r);
|
|
//Create an XML document node
|
|
XDocument doc = new XDocument(
|
|
new XElement("PPG",
|
|
new XElement("Header",
|
|
new XElement("Protocol", new XElement("Message", "PaintShopInterface"), new XElement("Name", "PPG"), new XElement("Version", "1.5.0")),
|
|
new XElement("Transaction",
|
|
new XElement("TransactionID", null),
|
|
new XElement("TransactionDate", DateTime.Now.ToString("yyyy-MM-hh:mm:ss"))
|
|
),
|
|
new XElement("Product",
|
|
new XElement("Name", "ImEX Online"),
|
|
new XElement("Version", null)
|
|
)
|
|
|
|
),
|
|
new XElement("DataInterface",
|
|
new XElement("ROData",
|
|
new XElement("ShopInfo",
|
|
new XElement("ShopID", data?.bodyshops_by_pk?.imexshopid?.Value),
|
|
new XElement("ShopName", data?.bodyshops_by_pk?.shopname?.Value)
|
|
),
|
|
new XElement("RepairOrders",
|
|
new XElement("ROCount", data?.jobs?.Count)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
);
|
|
|
|
foreach (dynamic job in data.jobs)
|
|
{
|
|
|
|
|
|
logger.Debug($"{job.ro_number}");
|
|
doc.Element("PPG").Element("DataInterface").Element("ROData").Element("RepairOrders").Add(new XElement("RO",
|
|
new XElement("RONumber", job.ro_number?.Value),
|
|
new XElement("ROStatus", "Open"),
|
|
new XElement("Customer", $"{job.ownr_ln}, {job.ownr_fn}"),
|
|
new XElement("ROPainterNotes", ""),
|
|
new XElement("LicensePlateNum", job.plate_no?.Value),
|
|
new XElement("VIN", job.v_vin?.Value),
|
|
new XElement("ModelYear", job.v_model_yr?.Value),
|
|
new XElement("MakeDesc", job.v_make_desc?.Value),
|
|
new XElement("ModelName", job.v_model_desc?.Value),
|
|
new XElement("OEMColorCode", job.vehicle != null ? job.vehicle?.v_paint_codes == null ? "a" : job.vehicle?.v_paint_codes?.paint_cd1.Value : "b"),
|
|
new XElement("RefinishLaborHours", job.larhrs?.aggregate?.sum.mod_lb_hrs?.Value),
|
|
new XElement("InsuranceCompanyName", job.ins_co_nm?.Value),
|
|
new XElement("EstimatorName", $"{job.est_ct_ln}, {job.est_ct_fn}"),
|
|
new XElement("PaintMaterialsRevenue", ((float)(job.job_totals != null ? job.job_totals?.rates?.mapa?.total?.amount?.Value : 0)) / 100),
|
|
new XElement("PaintMaterialsRate", job.rate_mapa?.Value),
|
|
new XElement("BodyHours", job.labhrs?.aggregate.sum?.mod_lb_hrs?.Value),
|
|
new XElement("BodyLaborRate", job.rate_lab?.Value),
|
|
new XElement("TotalCostOfRepairs", ((float)(job.job_totals != null ? job.job_totals?.totals?.subtotal?.amount?.Value : 0)) / 100)
|
|
|
|
|
|
));
|
|
|
|
}
|
|
|
|
Directory.CreateDirectory(Properties.Settings.Default.PaintScalePath);
|
|
|
|
doc.Save(Properties.Settings.Default.PaintScalePath + @"\PPGPaint.xml");
|
|
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger.Error(ex, "Error while pushing data to PPG paint scale.");
|
|
}
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|