Merged in release/2022-04-29 (pull request #455)
release/2022-04-29 Approved-by: Patrick Fic
This commit is contained in:
@@ -14493,6 +14493,27 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>priorsuccesfulexport</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
<default_text></default_text>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-MX</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-CA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
</children>
|
||||
</folder_node>
|
||||
</children>
|
||||
@@ -32395,6 +32416,27 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>orderinhouse</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
<default_text></default_text>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-MX</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-CA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
</children>
|
||||
</folder_node>
|
||||
</children>
|
||||
|
||||
@@ -13,6 +13,7 @@ import QboAuthorizeComponent from "../qbo-authorize/qbo-authorize.component";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import ExportLogsCountDisplay from "../export-logs-count-display/export-logs-count-display.component";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop,
|
||||
@@ -131,11 +132,9 @@ export function AccountingPayablesTableComponent({ bodyshop, loading, bills }) {
|
||||
dataIndex: "attempts",
|
||||
key: "attempts",
|
||||
|
||||
render: (text, record) => {
|
||||
const success = record.exportlogs.filter((e) => e.successful).length;
|
||||
const attempts = record.exportlogs.length;
|
||||
return `${success}/${attempts}`;
|
||||
},
|
||||
render: (text, record) => (
|
||||
<ExportLogsCountDisplay logs={record.exportlogs} />
|
||||
),
|
||||
},
|
||||
{
|
||||
title: t("general.labels.actions"),
|
||||
|
||||
@@ -13,6 +13,7 @@ import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import OwnerNameDisplay from "../owner-name-display/owner-name-display.component";
|
||||
import ExportLogsCountDisplay from "../export-logs-count-display/export-logs-count-display.component";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop,
|
||||
@@ -130,11 +131,9 @@ export function AccountingPayablesTableComponent({
|
||||
dataIndex: "attempts",
|
||||
key: "attempts",
|
||||
|
||||
render: (text, record) => {
|
||||
const success = record.exportlogs.filter((e) => e.successful).length;
|
||||
const attempts = record.exportlogs.length;
|
||||
return `${success}/${attempts}`;
|
||||
},
|
||||
render: (text, record) => (
|
||||
<ExportLogsCountDisplay logs={record.exportlogs} />
|
||||
),
|
||||
},
|
||||
{
|
||||
title: t("general.labels.actions"),
|
||||
|
||||
@@ -14,6 +14,7 @@ import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import QboAuthorizeComponent from "../qbo-authorize/qbo-authorize.component";
|
||||
import { DateFormatter } from "../../utils/DateFormatter";
|
||||
import OwnerNameDisplay from "../owner-name-display/owner-name-display.component";
|
||||
import ExportLogsCountDisplay from "../export-logs-count-display/export-logs-count-display.component";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop,
|
||||
@@ -139,12 +140,9 @@ export function AccountingReceivablesTableComponent({
|
||||
title: t("exportlogs.labels.attempts"),
|
||||
dataIndex: "attempts",
|
||||
key: "attempts",
|
||||
|
||||
render: (text, record) => {
|
||||
const success = record.exportlogs.filter((e) => e.successful).length;
|
||||
const attempts = record.exportlogs.length;
|
||||
return `${success}/${attempts}`;
|
||||
},
|
||||
render: (text, record) => (
|
||||
<ExportLogsCountDisplay logs={record.exportlogs} />
|
||||
),
|
||||
},
|
||||
{
|
||||
title: t("general.labels.actions"),
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
import React from "react";
|
||||
import { WarningOutlined } from "@ant-design/icons";
|
||||
import { Space, Tooltip } from "antd";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const style = {
|
||||
fontWeight: "bold",
|
||||
color: "green",
|
||||
};
|
||||
|
||||
export default function ExportLogsCountDisplay({ logs }) {
|
||||
const success = logs.filter((e) => e.successful).length;
|
||||
const attempts = logs.length;
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<Space style={success > 0 ? style : {}}>
|
||||
{`${success}/${attempts}`}
|
||||
{success > 0 && (
|
||||
<Tooltip title={t("exportlogs.labels.priorsuccesfulexport")}>
|
||||
<WarningOutlined />
|
||||
</Tooltip>
|
||||
)}
|
||||
</Space>
|
||||
);
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
EditFilled,
|
||||
PlusCircleTwoTone,
|
||||
MinusCircleTwoTone,
|
||||
HomeOutlined,
|
||||
} from "@ant-design/icons";
|
||||
import { useMutation } from "@apollo/client";
|
||||
import {
|
||||
@@ -42,6 +43,7 @@ import _ from "lodash";
|
||||
import JobCreateIOU from "../job-create-iou/job-create-iou.component";
|
||||
import JobLinesExpander from "./job-lines-expander.component";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import moment from "moment";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop,
|
||||
@@ -54,6 +56,8 @@ const mapDispatchToProps = (dispatch) => ({
|
||||
dispatch(setModalContext({ context: context, modal: "jobLineEdit" })),
|
||||
setPartsOrderContext: (context) =>
|
||||
dispatch(setModalContext({ context: context, modal: "partsOrder" })),
|
||||
setBillEnterContext: (context) =>
|
||||
dispatch(setModalContext({ context: context, modal: "billEnter" })),
|
||||
});
|
||||
|
||||
export function JobLinesComponent({
|
||||
@@ -68,6 +72,7 @@ export function JobLinesComponent({
|
||||
job,
|
||||
setJobLineEditContext,
|
||||
form,
|
||||
setBillEnterContext,
|
||||
}) {
|
||||
const [deleteJobLine] = useMutation(DELETE_JOB_LINE_BY_PK);
|
||||
|
||||
@@ -386,6 +391,62 @@ export function JobLinesComponent({
|
||||
</Space>
|
||||
</Tag>
|
||||
)}
|
||||
<Button
|
||||
disabled={
|
||||
(job && !job.converted) ||
|
||||
(selectedLines.length > 0 ? false : true) ||
|
||||
jobRO ||
|
||||
technician
|
||||
}
|
||||
onClick={() => {
|
||||
// setPartsOrderContext({
|
||||
// actions: { refetch: refetch },
|
||||
// context: {
|
||||
// jobId: job.id,
|
||||
// job: job,
|
||||
// linesToOrder: selectedLines,
|
||||
// },
|
||||
// });
|
||||
|
||||
setBillEnterContext({
|
||||
actions: { refetch: refetch },
|
||||
context: {
|
||||
disableInvNumber: true,
|
||||
job: { id: job.id },
|
||||
bill: {
|
||||
vendorid: bodyshop.inhousevendorid,
|
||||
invoice_number: "ih",
|
||||
isinhouse: true,
|
||||
date: new moment(),
|
||||
total: 0,
|
||||
billlines: selectedLines.map((p) => {
|
||||
return {
|
||||
joblineid: p.id,
|
||||
actual_price: p.act_price,
|
||||
actual_cost: 0, //p.act_price,
|
||||
line_desc: p.line_desc,
|
||||
line_remarks: p.line_remarks,
|
||||
part_type: p.part_type,
|
||||
quantity: p.quantity || 1,
|
||||
applicable_taxes: {
|
||||
local: false,
|
||||
state: false,
|
||||
federal: false,
|
||||
},
|
||||
};
|
||||
}),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
//Clear out the selected lines. IO-785
|
||||
setSelectedLines([]);
|
||||
}}
|
||||
>
|
||||
<HomeOutlined />
|
||||
{t("parts.actions.orderinhouse")}
|
||||
{selectedLines.length > 0 && ` (${selectedLines.length})`}
|
||||
</Button>
|
||||
<Button
|
||||
disabled={
|
||||
(job && !job.converted) ||
|
||||
|
||||
@@ -141,7 +141,9 @@ export function JobLinesUpsertModalComponent({
|
||||
rules={[
|
||||
({ getFieldValue }) => ({
|
||||
validator(rule, value) {
|
||||
if (!!getFieldValue("mod_lbr_ty") === !!value) {
|
||||
if (
|
||||
!!getFieldValue("mod_lbr_ty") === (!!value || value === 0)
|
||||
) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
return Promise.reject(
|
||||
|
||||
@@ -146,7 +146,11 @@ export function JobsCreateJobsInfo({ bodyshop, form, selected }) {
|
||||
</Form.Item>
|
||||
</LayoutFormRow>
|
||||
</Collapse.Panel>
|
||||
<Collapse.Panel forceRender key="claim" header={t("menus.jobsdetail.claimdetail")}>
|
||||
<Collapse.Panel
|
||||
forceRender
|
||||
key="claim"
|
||||
header={t("menus.jobsdetail.claimdetail")}
|
||||
>
|
||||
<LayoutFormRow>
|
||||
<Form.Item label={t("jobs.fields.loss_desc")} name="loss_desc">
|
||||
<Input />
|
||||
@@ -193,7 +197,8 @@ export function JobsCreateJobsInfo({ bodyshop, form, selected }) {
|
||||
</Form.Item>
|
||||
</LayoutFormRow>
|
||||
</Collapse.Panel>
|
||||
<Collapse.Panel forceRender
|
||||
<Collapse.Panel
|
||||
forceRender
|
||||
key="financial"
|
||||
header={t("menus.jobsdetail.financials")}
|
||||
>
|
||||
@@ -204,7 +209,7 @@ export function JobsCreateJobsInfo({ bodyshop, form, selected }) {
|
||||
<CurrencyInput min={0} />
|
||||
</Form.Item>
|
||||
<Form.Item label={t("jobs.fields.ded_status")} name="ded_status">
|
||||
<Select>
|
||||
<Select allowClear>
|
||||
<Select.Option value="W">
|
||||
{t("jobs.labels.deductible.waived")}
|
||||
</Select.Option>
|
||||
|
||||
@@ -912,7 +912,8 @@
|
||||
"createdat": "Created At"
|
||||
},
|
||||
"labels": {
|
||||
"attempts": "Export Attempts"
|
||||
"attempts": "Export Attempts",
|
||||
"priorsuccesfulexport": "This record has previously been exported successfully. Please make sure it has already been deleted in the target system."
|
||||
}
|
||||
},
|
||||
"general": {
|
||||
@@ -1916,7 +1917,8 @@
|
||||
},
|
||||
"parts": {
|
||||
"actions": {
|
||||
"order": "Order Parts"
|
||||
"order": "Order Parts",
|
||||
"orderinhouse": "Order as In House"
|
||||
}
|
||||
},
|
||||
"parts_orders": {
|
||||
|
||||
@@ -912,7 +912,8 @@
|
||||
"createdat": ""
|
||||
},
|
||||
"labels": {
|
||||
"attempts": ""
|
||||
"attempts": "",
|
||||
"priorsuccesfulexport": ""
|
||||
}
|
||||
},
|
||||
"general": {
|
||||
@@ -1916,7 +1917,8 @@
|
||||
},
|
||||
"parts": {
|
||||
"actions": {
|
||||
"order": "Pedido de piezas"
|
||||
"order": "Pedido de piezas",
|
||||
"orderinhouse": ""
|
||||
}
|
||||
},
|
||||
"parts_orders": {
|
||||
|
||||
@@ -912,7 +912,8 @@
|
||||
"createdat": ""
|
||||
},
|
||||
"labels": {
|
||||
"attempts": ""
|
||||
"attempts": "",
|
||||
"priorsuccesfulexport": ""
|
||||
}
|
||||
},
|
||||
"general": {
|
||||
@@ -1916,7 +1917,8 @@
|
||||
},
|
||||
"parts": {
|
||||
"actions": {
|
||||
"order": "Commander des pièces"
|
||||
"order": "Commander des pièces",
|
||||
"orderinhouse": ""
|
||||
}
|
||||
},
|
||||
"parts_orders": {
|
||||
|
||||
@@ -779,6 +779,13 @@
|
||||
table:
|
||||
schema: public
|
||||
name: timetickets
|
||||
- name: transitions
|
||||
using:
|
||||
foreign_key_constraint_on:
|
||||
column: bodyshopid
|
||||
table:
|
||||
schema: public
|
||||
name: transitions
|
||||
- name: vehicles
|
||||
using:
|
||||
foreign_key_constraint_on:
|
||||
@@ -2596,6 +2603,13 @@
|
||||
insertion_order: null
|
||||
column_mapping:
|
||||
id: jobid
|
||||
- name: mixdata
|
||||
using:
|
||||
foreign_key_constraint_on:
|
||||
column: jobid
|
||||
table:
|
||||
schema: public
|
||||
name: mixdata
|
||||
- name: notes
|
||||
using:
|
||||
foreign_key_constraint_on:
|
||||
@@ -2645,6 +2659,13 @@
|
||||
table:
|
||||
schema: public
|
||||
name: timetickets
|
||||
- name: transitions
|
||||
using:
|
||||
foreign_key_constraint_on:
|
||||
column: jobid
|
||||
table:
|
||||
schema: public
|
||||
name: transitions
|
||||
insert_permissions:
|
||||
- role: user
|
||||
permission:
|
||||
@@ -3590,6 +3611,84 @@
|
||||
_eq: X-Hasura-User-Id
|
||||
- active:
|
||||
_eq: true
|
||||
- table:
|
||||
schema: public
|
||||
name: mixdata
|
||||
object_relationships:
|
||||
- name: job
|
||||
using:
|
||||
foreign_key_constraint_on: jobid
|
||||
insert_permissions:
|
||||
- role: user
|
||||
permission:
|
||||
check:
|
||||
job:
|
||||
bodyshop:
|
||||
associations:
|
||||
_and:
|
||||
- active:
|
||||
_eq: true
|
||||
- user:
|
||||
authid:
|
||||
_eq: X-Hasura-User-Id
|
||||
columns:
|
||||
- mixdata
|
||||
- totalliquidcost
|
||||
- totalsundrycost
|
||||
- company
|
||||
- version
|
||||
- created_at
|
||||
- updated_at
|
||||
- id
|
||||
- jobid
|
||||
backend_only: false
|
||||
select_permissions:
|
||||
- role: user
|
||||
permission:
|
||||
columns:
|
||||
- mixdata
|
||||
- totalliquidcost
|
||||
- totalsundrycost
|
||||
- company
|
||||
- version
|
||||
- created_at
|
||||
- updated_at
|
||||
- id
|
||||
- jobid
|
||||
filter:
|
||||
job:
|
||||
bodyshop:
|
||||
associations:
|
||||
_and:
|
||||
- active:
|
||||
_eq: true
|
||||
- user:
|
||||
authid:
|
||||
_eq: X-Hasura-User-Id
|
||||
update_permissions:
|
||||
- role: user
|
||||
permission:
|
||||
columns:
|
||||
- mixdata
|
||||
- totalliquidcost
|
||||
- totalsundrycost
|
||||
- company
|
||||
- version
|
||||
- created_at
|
||||
- updated_at
|
||||
- id
|
||||
- jobid
|
||||
filter:
|
||||
job:
|
||||
bodyshop:
|
||||
associations:
|
||||
_and:
|
||||
- active:
|
||||
_eq: true
|
||||
- user:
|
||||
authid:
|
||||
_eq: X-Hasura-User-Id
|
||||
check: null
|
||||
- table:
|
||||
schema: public
|
||||
name: notes
|
||||
@@ -4597,6 +4696,93 @@
|
||||
_eq: X-Hasura-User-Id
|
||||
- active:
|
||||
_eq: true
|
||||
- table:
|
||||
schema: public
|
||||
name: transitions
|
||||
object_relationships:
|
||||
- name: bodyshop
|
||||
using:
|
||||
foreign_key_constraint_on: bodyshopid
|
||||
- name: job
|
||||
using:
|
||||
foreign_key_constraint_on: jobid
|
||||
insert_permissions:
|
||||
- role: user
|
||||
permission:
|
||||
check:
|
||||
bodyshop:
|
||||
associations:
|
||||
_and:
|
||||
- active:
|
||||
_eq: true
|
||||
- user:
|
||||
authid:
|
||||
_eq: X-Hasura-User-Id
|
||||
columns:
|
||||
- bodyshopid
|
||||
- created_at
|
||||
- duration
|
||||
- end
|
||||
- id
|
||||
- jobid
|
||||
- next_value
|
||||
- prev_value
|
||||
- start
|
||||
- type
|
||||
- updated_at
|
||||
- value
|
||||
backend_only: false
|
||||
select_permissions:
|
||||
- role: user
|
||||
permission:
|
||||
columns:
|
||||
- duration
|
||||
- next_value
|
||||
- prev_value
|
||||
- type
|
||||
- value
|
||||
- created_at
|
||||
- end
|
||||
- start
|
||||
- updated_at
|
||||
- bodyshopid
|
||||
- id
|
||||
- jobid
|
||||
filter:
|
||||
bodyshop:
|
||||
associations:
|
||||
_and:
|
||||
- active:
|
||||
_eq: true
|
||||
- user:
|
||||
authid:
|
||||
_eq: X-Hasura-User-Id
|
||||
update_permissions:
|
||||
- role: user
|
||||
permission:
|
||||
columns:
|
||||
- duration
|
||||
- next_value
|
||||
- prev_value
|
||||
- type
|
||||
- value
|
||||
- created_at
|
||||
- end
|
||||
- start
|
||||
- updated_at
|
||||
- bodyshopid
|
||||
- id
|
||||
- jobid
|
||||
filter:
|
||||
bodyshop:
|
||||
associations:
|
||||
_and:
|
||||
- active:
|
||||
_eq: true
|
||||
- user:
|
||||
authid:
|
||||
_eq: X-Hasura-User-Id
|
||||
check: {}
|
||||
- table:
|
||||
schema: public
|
||||
name: users
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
DROP TABLE "public"."transitions";
|
||||
@@ -0,0 +1,18 @@
|
||||
CREATE TABLE "public"."transitions" ("id" uuid NOT NULL DEFAULT gen_random_uuid(), "created_at" timestamptz NOT NULL DEFAULT now(), "updated_at" timestamptz NOT NULL DEFAULT now(), "bodyshoipid" uuid NOT NULL, "start" timestamptz NOT NULL, "end" timestamptz, "duration" numeric DEFAULT 0, "prev_value" text, "value" text, "next_value" Text, "jobid" uuid, "type" text NOT NULL, PRIMARY KEY ("id") , FOREIGN KEY ("bodyshoipid") REFERENCES "public"."bodyshops"("id") ON UPDATE cascade ON DELETE cascade, FOREIGN KEY ("jobid") REFERENCES "public"."jobs"("id") ON UPDATE cascade ON DELETE cascade);
|
||||
CREATE OR REPLACE FUNCTION "public"."set_current_timestamp_updated_at"()
|
||||
RETURNS TRIGGER AS $$
|
||||
DECLARE
|
||||
_new record;
|
||||
BEGIN
|
||||
_new := NEW;
|
||||
_new."updated_at" = NOW();
|
||||
RETURN _new;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
CREATE TRIGGER "set_public_transitions_updated_at"
|
||||
BEFORE UPDATE ON "public"."transitions"
|
||||
FOR EACH ROW
|
||||
EXECUTE PROCEDURE "public"."set_current_timestamp_updated_at"();
|
||||
COMMENT ON TRIGGER "set_public_transitions_updated_at" ON "public"."transitions"
|
||||
IS 'trigger to set value of column "updated_at" to current timestamp on row update';
|
||||
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
||||
@@ -0,0 +1 @@
|
||||
alter table "public"."transitions" rename column "bodyshopid" to "bodyshoipid";
|
||||
@@ -0,0 +1 @@
|
||||
alter table "public"."transitions" rename column "bodyshoipid" to "bodyshopid";
|
||||
@@ -0,0 +1 @@
|
||||
DROP TABLE "public"."mixdata";
|
||||
@@ -0,0 +1,18 @@
|
||||
CREATE TABLE "public"."mixdata" ("id" uuid NOT NULL DEFAULT gen_random_uuid(), "created_at" timestamptz NOT NULL DEFAULT now(), "updated_at" timestamptz NOT NULL DEFAULT now(), "jobid" uuid NOT NULL, "company" text NOT NULL, "version" text NOT NULL, "totalliquidcost" numeric NOT NULL, "totalsundrycost" numeric NOT NULL, "mixdata" jsonb, PRIMARY KEY ("id") , FOREIGN KEY ("jobid") REFERENCES "public"."jobs"("id") ON UPDATE cascade ON DELETE cascade);
|
||||
CREATE OR REPLACE FUNCTION "public"."set_current_timestamp_updated_at"()
|
||||
RETURNS TRIGGER AS $$
|
||||
DECLARE
|
||||
_new record;
|
||||
BEGIN
|
||||
_new := NEW;
|
||||
_new."updated_at" = NOW();
|
||||
RETURN _new;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
CREATE TRIGGER "set_public_mixdata_updated_at"
|
||||
BEFORE UPDATE ON "public"."mixdata"
|
||||
FOR EACH ROW
|
||||
EXECUTE PROCEDURE "public"."set_current_timestamp_updated_at"();
|
||||
COMMENT ON TRIGGER "set_public_mixdata_updated_at" ON "public"."mixdata"
|
||||
IS 'trigger to set value of column "updated_at" to current timestamp on row update';
|
||||
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
||||
@@ -39,6 +39,7 @@
|
||||
"lodash": "^4.17.21",
|
||||
"moment": "^2.29.3",
|
||||
"moment-timezone": "^0.5.34",
|
||||
"multer": "^1.4.4",
|
||||
"node-mailjet": "^3.3.10",
|
||||
"node-quickbooks": "^2.0.39",
|
||||
"nodemailer": "^6.7.3",
|
||||
@@ -50,6 +51,7 @@
|
||||
"stripe": "^8.217.0",
|
||||
"twilio": "^3.76.1",
|
||||
"uuid": "^8.3.2",
|
||||
"xml2js": "^0.4.23",
|
||||
"xmlbuilder2": "^3.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
17
server.js
17
server.js
@@ -7,7 +7,8 @@ const twilio = require("twilio");
|
||||
const logger = require("./server/utils/logger");
|
||||
var fb = require("./server/firebase/firebase-handler");
|
||||
var cookieParser = require("cookie-parser");
|
||||
|
||||
const multer = require("multer");
|
||||
const upload = multer();
|
||||
//var enforce = require("express-sslify");
|
||||
|
||||
require("dotenv").config({
|
||||
@@ -123,6 +124,11 @@ app.post("/sms/markConversationRead", smsStatus.markConversationRead);
|
||||
|
||||
var job = require("./server/job/job");
|
||||
app.post("/job/totals", fb.validateFirebaseIdToken, job.totals);
|
||||
app.post(
|
||||
"/job/statustransition",
|
||||
fb.validateFirebaseIdToken,
|
||||
job.statustransition
|
||||
);
|
||||
app.post("/job/totalsssu", fb.validateFirebaseIdToken, job.totalsSsu);
|
||||
app.post("/job/costing", fb.validateFirebaseIdToken, job.costing);
|
||||
app.post("/job/costingmulti", fb.validateFirebaseIdToken, job.costingmulti);
|
||||
@@ -181,6 +187,15 @@ app.post("/data/arms", data.arms);
|
||||
var taskHandler = require("./server/tasks/tasks");
|
||||
app.post("/taskHandler", taskHandler.taskHandler);
|
||||
|
||||
var mixdataUpload = require("./server/mixdata/mixdata");
|
||||
|
||||
app.post(
|
||||
"/mixdata/upload",
|
||||
fb.validateFirebaseIdToken,
|
||||
upload.any(),
|
||||
mixdataUpload.mixdataUpload
|
||||
);
|
||||
|
||||
var ioevent = require("./server/ioevent/ioevent");
|
||||
app.post("/ioevent", ioevent.default);
|
||||
app.post("/newlog", (req, res) => {
|
||||
|
||||
@@ -198,6 +198,8 @@ async function QueryJobData(socket, jobid) {
|
||||
|
||||
async function QueryVehicleFromDms(socket) {
|
||||
try {
|
||||
if (!socket.JobData.v_vin) return null;
|
||||
|
||||
const { data: VehicleGetResponse, request } = await axios.post(
|
||||
PBS_ENDPOINTS.VehicleGet,
|
||||
{
|
||||
|
||||
@@ -637,6 +637,13 @@ exports.default = function ({
|
||||
});
|
||||
}
|
||||
|
||||
if (!qbo && InvoiceLineAdd.length === 0) {
|
||||
//Handle the scenario where there is a $0 sale invoice.
|
||||
InvoiceLineAdd.push({
|
||||
Desc: "No estimate lines.",
|
||||
});
|
||||
}
|
||||
|
||||
return InvoiceLineAdd;
|
||||
};
|
||||
|
||||
|
||||
@@ -1489,3 +1489,49 @@ mutation INSERT_EXPORT_LOG($log: exportlog_insert_input!) {
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
exports.QUERY_EXISTING_TRANSITION = `
|
||||
mutation INSERT_EXPORT_LOG($log: exportlog_insert_input!) {
|
||||
insert_exportlog_one(object: $log) {
|
||||
id
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
exports.UPDATE_OLD_TRANSITION = `mutation UPDATE_OLD_TRANSITION($jobid: uuid!, $existingTransition: transitions_set_input!){
|
||||
update_transitions(where:{jobid:{_eq:$jobid}, end:{_is_null:true
|
||||
}}, _set:$existingTransition){
|
||||
affected_rows
|
||||
returning{
|
||||
id
|
||||
start
|
||||
end
|
||||
prev_value
|
||||
next_value
|
||||
value
|
||||
}
|
||||
}
|
||||
}`;
|
||||
|
||||
exports.INSERT_NEW_TRANSITION = `mutation INSERT_NEW_TRANSITION($newTransition: transitions_insert_input!, $oldTransitionId: uuid, $duration: numeric) {
|
||||
insert_transitions_one(object: $newTransition) {
|
||||
id
|
||||
}
|
||||
update_transitions(where: {id: {_eq: $oldTransitionId}}, _set: {duration: $duration}) {
|
||||
affected_rows
|
||||
}
|
||||
}
|
||||
|
||||
`;
|
||||
|
||||
exports.QUERY_JOB_ID_MIXDATA = `query QUERY_JOB_ID_MIXDATA($roNumbers: [String!]!) {
|
||||
jobs(where: {ro_number: {_in: $roNumbers}}) {
|
||||
id
|
||||
ro_number
|
||||
mixdata {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
`;
|
||||
84
server/job/job-status-transition.js
Normal file
84
server/job/job-status-transition.js
Normal file
@@ -0,0 +1,84 @@
|
||||
const Dinero = require("dinero.js");
|
||||
const queries = require("../graphql-client/queries");
|
||||
//const client = require("../graphql-client/graphql-client").client;
|
||||
const _ = require("lodash");
|
||||
const GraphQLClient = require("graphql-request").GraphQLClient;
|
||||
const logger = require("../utils/logger");
|
||||
// Dinero.defaultCurrency = "USD";
|
||||
// Dinero.globalLocale = "en-CA";
|
||||
Dinero.globalRoundingMode = "HALF_EVEN";
|
||||
|
||||
async function StatusTransition(req, res) {
|
||||
const { jobid, value, bodyshopid } = req.body;
|
||||
|
||||
const BearerToken = req.headers.authorization;
|
||||
logger.log("job-costing-start", "DEBUG", req.user.email, jobid, null);
|
||||
const client = new GraphQLClient(process.env.GRAPHQL_ENDPOINT, {
|
||||
headers: {
|
||||
Authorization: BearerToken,
|
||||
},
|
||||
});
|
||||
|
||||
try {
|
||||
const { update_transitions } = await client
|
||||
.setHeaders({ Authorization: BearerToken })
|
||||
.request(queries.UPDATE_OLD_TRANSITION, {
|
||||
jobid: jobid,
|
||||
existingTransition: {
|
||||
end: new Date(),
|
||||
next_value: value,
|
||||
|
||||
//duration
|
||||
},
|
||||
});
|
||||
|
||||
let duration =
|
||||
update_transitions.affected_rows === 0
|
||||
? 0
|
||||
: new Date(update_transitions.returning[0].end) -
|
||||
new Date(update_transitions.returning[0].start);
|
||||
|
||||
const resp2 = await client
|
||||
.setHeaders({ Authorization: BearerToken })
|
||||
.request(queries.INSERT_NEW_TRANSITION, {
|
||||
oldTransitionId:
|
||||
update_transitions.affected_rows === 0
|
||||
? null
|
||||
: update_transitions.returning[0].id,
|
||||
duration,
|
||||
newTransition: {
|
||||
bodyshopid: bodyshopid,
|
||||
jobid: jobid,
|
||||
start:
|
||||
update_transitions.affected_rows === 0
|
||||
? new Date()
|
||||
: update_transitions.returning[0].end,
|
||||
prev_value:
|
||||
update_transitions.affected_rows === 0
|
||||
? null
|
||||
: update_transitions.returning[0].value,
|
||||
value: value,
|
||||
type: "status",
|
||||
},
|
||||
});
|
||||
|
||||
//Check to see if there is an existing status transition record.
|
||||
//Query using Job ID, start is not null, end is null.
|
||||
|
||||
//If there is no existing record, this is the start of the transition life cycle.
|
||||
// Create the initial transition record.
|
||||
|
||||
//If there is a current status transition record, update it with the end date, duration, and next value.
|
||||
|
||||
res.sendStatus(200); //.json(ret);
|
||||
} catch (error) {
|
||||
logger.log("job-costing-error", "ERROR", req.user.email, jobid, {
|
||||
message: error.message,
|
||||
stack: error.stack,
|
||||
});
|
||||
|
||||
res.status(400).send(JSON.stringify(error));
|
||||
}
|
||||
}
|
||||
|
||||
exports.statustransition = StatusTransition;
|
||||
@@ -2,3 +2,4 @@ exports.totals = require("./job-totals").default;
|
||||
exports.totalsSsu = require("./job-totals").totalsSsu;
|
||||
exports.costing = require("./job-costing").JobCosting;
|
||||
exports.costingmulti = require("./job-costing").JobCostingMulti;
|
||||
exports.statustransition = require("./job-status-transition").statustransition;
|
||||
|
||||
206
server/mixdata/PPGSampleData.json
Normal file
206
server/mixdata/PPGSampleData.json
Normal file
@@ -0,0 +1,206 @@
|
||||
{
|
||||
"PPG": {
|
||||
"Header": {
|
||||
"Protocol": {
|
||||
"Message": "MixDataInterface",
|
||||
"Name": "PPG",
|
||||
"Version": "1.3.0"
|
||||
},
|
||||
"Transaction": {
|
||||
"TransactionID": "3F2504E0-4F89-11D3-9A0C-0305E82C3301",
|
||||
"TransactionDate": "2006-06-06T15:00:00"
|
||||
},
|
||||
"ShopInfo": {
|
||||
"ShopID": "SomeShopID",
|
||||
"ShopName": "Some Body Shop"
|
||||
}
|
||||
},
|
||||
"DataExportInterface": {
|
||||
"ROData": {
|
||||
"ROCount": "2",
|
||||
"RepairOrders": {
|
||||
"RO": [
|
||||
{
|
||||
"ROCounter": "1",
|
||||
"RONumber": "27187",
|
||||
"Notes": "This is a painter note",
|
||||
"Undercoat": "False",
|
||||
"Clearcoat": "False",
|
||||
"Basecoat": "True",
|
||||
"TotalLiquidCost": "133.26",
|
||||
"TotalSundryCost": "47.12",
|
||||
"MixCount": "2",
|
||||
"Mixes": {
|
||||
"Mix": [
|
||||
{
|
||||
"MixCounter": "1",
|
||||
"MixRONumber": "27187",
|
||||
"MixedDate": "2008-09-17T00:00:00",
|
||||
"MixedBy": "Tony Blair",
|
||||
"MixedByEmployeeID": "5>",
|
||||
"PPGBrandCode": "ABC",
|
||||
"MixCost": "83.49",
|
||||
"FormulaType": "Standard",
|
||||
"ComponentCount": "5",
|
||||
"Components": {
|
||||
"Component": [
|
||||
{
|
||||
"ComponentCounter": "1",
|
||||
"ComponentRONumber": "27187",
|
||||
"ComponentCode": "P425-900",
|
||||
"ComponentDescription": "F3550 CLEAR",
|
||||
"ComponentCost": "44.84",
|
||||
"ComponentWeightApplied": "521.5347",
|
||||
"ComponentWeightTarget": "525.4023",
|
||||
"ComponentDensity": "1.311"
|
||||
},
|
||||
{
|
||||
"ComponentCounter": "2",
|
||||
"ComponentRONumber": "27187",
|
||||
"ComponentCode": "P425-948",
|
||||
"ComponentDescription": "H/S BLACK",
|
||||
"ComponentCost": "13.77",
|
||||
"ComponentWeightApplied": "118.5779",
|
||||
"ComponentWeightTarget": "118.5832",
|
||||
"ComponentDensity": "0.971"
|
||||
},
|
||||
{
|
||||
"ComponentCounter": "3",
|
||||
"ComponentRONumber": "27187",
|
||||
"ComponentCode": "P425-921",
|
||||
"ComponentDescription": "H/S CLARET",
|
||||
"ComponentCost": "0.24",
|
||||
"ComponentWeightApplied": "2.082",
|
||||
"ComponentWeightTarget": "2.1022",
|
||||
"ComponentDensity": "0.976"
|
||||
},
|
||||
{
|
||||
"ComponentCounter": "4",
|
||||
"ComponentRONumber": "27187",
|
||||
"ComponentCode": "P425-937",
|
||||
"ComponentDescription": "PALE YELLOW",
|
||||
"ComponentCost": "2.85",
|
||||
"ComponentWeightApplied": "20.4412",
|
||||
"ComponentWeightTarget": "20.4888",
|
||||
"ComponentDensity": "1.136"
|
||||
},
|
||||
{
|
||||
"ComponentCounter": "5",
|
||||
"ComponentRONumber": "27187",
|
||||
"ComponentCode": "P425-948",
|
||||
"ComponentDescription": "Matting Agent",
|
||||
"ComponentCost": "21.79",
|
||||
"ComponentWeightApplied": "414.8808",
|
||||
"ComponentWeightTarget": "414.8798",
|
||||
"ComponentDensity": "0.987"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"MixCounter": "2",
|
||||
"MixRONumber": "27187",
|
||||
"MixedDate": "2008-09-17T00:00:00",
|
||||
"MixedBy": "Bill Clinton",
|
||||
"MixedByEmployeeID": "42>",
|
||||
"PPGBrandCode": "DEF",
|
||||
"MixCost": "49.76",
|
||||
"FormulaType": "RFU",
|
||||
"ComponentCount": "2",
|
||||
"Components": {
|
||||
"Component": [
|
||||
{
|
||||
"ComponentCounter": "1",
|
||||
"ComponentRONumber": "27187",
|
||||
"ComponentCode": "P850-1401",
|
||||
"ComponentDescription": "Fade-Out Thinner",
|
||||
"ComponentCost": "17.34",
|
||||
"ComponentWeightApplied": "837.1649",
|
||||
"ComponentWeightTarget": "838.2232",
|
||||
"ComponentDensity": "0.8716"
|
||||
},
|
||||
{
|
||||
"ComponentCounter": "2",
|
||||
"ComponentRONumber": "27187",
|
||||
"ComponentCode": "P190-478",
|
||||
"ComponentDescription": "Ultraclear",
|
||||
"ComponentCost": "32.42",
|
||||
"ComponentWeightApplied": "862.5329",
|
||||
"ComponentWeightTarget": "870.3238",
|
||||
"ComponentDensity": "0.898"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"SundryCount": "1",
|
||||
"Sundries": {
|
||||
"Sundry": {
|
||||
"SundryCounter": "1",
|
||||
"SundryRONumber": "27187",
|
||||
"SundryAddedDate": "2008-09-17T00:00:00",
|
||||
"SundryAddedBy": "Tony Blair",
|
||||
"SundryCode": "Sundry1",
|
||||
"SundryDescription": "Bumper Prep Kit",
|
||||
"SundryCost": "23.56",
|
||||
"SundryQuantity": "2",
|
||||
"SundryQuantityUOM": "Each"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ROCounter": "2",
|
||||
"RONumber": "27320",
|
||||
"Notes": "This is a painter note too",
|
||||
"Undercoat": "True",
|
||||
"Clearcoat": "False",
|
||||
"Basecoat": "False",
|
||||
"TotalLiquidCost": "9.59",
|
||||
"TotalSundryCost": "0.0",
|
||||
"MixCount": "1",
|
||||
"Mixes": {
|
||||
"Mix": {
|
||||
"MixCounter": "1",
|
||||
"MixRONumber": "27320",
|
||||
"MixedDate": "2008-12-03T00:00:00",
|
||||
"MixedBy": "Jerry Primer",
|
||||
"MixedByEmployeeID": "87>",
|
||||
"PPGBrandCode": "GHI",
|
||||
"MixCost": "9.59",
|
||||
"FormulaType": "Standard",
|
||||
"ComponentCount": "2",
|
||||
"Components": {
|
||||
"Component": [
|
||||
{
|
||||
"ComponentCounter": "1",
|
||||
"ComponentRONumber": "27320",
|
||||
"ComponentCode": "P565-957",
|
||||
"ComponentDescription": "Long Life Etch",
|
||||
"ComponentCost": "5.31",
|
||||
"ComponentWeightApplied": "117.8754",
|
||||
"ComponentWeightTarget": "116.0129",
|
||||
"ComponentDensity": "0.9808"
|
||||
},
|
||||
{
|
||||
"ComponentCounter": "2",
|
||||
"ComponentRONumber": "27320",
|
||||
"ComponentCode": "P275-61",
|
||||
"ComponentDescription": "Acitvator For Long Life",
|
||||
"ComponentCost": "4.28",
|
||||
"ComponentWeightApplied": "103.4325",
|
||||
"ComponentWeightTarget": "101.3950",
|
||||
"ComponentDensity": "0.8571"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"SundryCount": "0"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
144
server/mixdata/mixdata.js
Normal file
144
server/mixdata/mixdata.js
Normal file
@@ -0,0 +1,144 @@
|
||||
const path = require("path");
|
||||
const _ = require("lodash");
|
||||
const logger = require("../utils/logger");
|
||||
const xml2js = require("xml2js");
|
||||
const GraphQLClient = require("graphql-request").GraphQLClient;
|
||||
const queries = require("../graphql-client/queries");
|
||||
|
||||
require("dotenv").config({
|
||||
path: path.resolve(
|
||||
process.cwd(),
|
||||
`.env.${process.env.NODE_ENV || "development"}`
|
||||
),
|
||||
});
|
||||
|
||||
exports.mixdataUpload = async (req, res) => {
|
||||
const { bodyshopid } = req.body;
|
||||
|
||||
const BearerToken = req.headers.authorization;
|
||||
logger.log("job-mixdata-upload", "DEBUG", req.user.email, null, null);
|
||||
const client = new GraphQLClient(process.env.GRAPHQL_ENDPOINT, {
|
||||
headers: {
|
||||
Authorization: BearerToken,
|
||||
},
|
||||
});
|
||||
|
||||
try {
|
||||
req.files.forEach(async (element) => {
|
||||
const b = Buffer.from(element.buffer);
|
||||
console.log(b.toString());
|
||||
|
||||
const inboundRequest = await xml2js.parseStringPromise(b.toString(), {
|
||||
explicitArray: false,
|
||||
});
|
||||
|
||||
const ScaleType = DetermineScaleType(inboundRequest);
|
||||
const RoNumbersFromInboundRequest = GetListOfRos(
|
||||
inboundRequest,
|
||||
ScaleType
|
||||
);
|
||||
|
||||
if (RoNumbersFromInboundRequest.length > 0) {
|
||||
//Query the list of ROs based on the RO number.
|
||||
const { jobs } = await client.request(queries.QUERY_JOB_ID_MIXDATA, {
|
||||
roNumbers: RoNumbersFromInboundRequest,
|
||||
});
|
||||
|
||||
//Create the hash for faster processing for inserts/updates.
|
||||
const jobHash = {};
|
||||
jobs.forEach((j) => {
|
||||
jobHash[j.ro_number] = {
|
||||
jobid: j.id,
|
||||
mixdataid: j.mixdata.length > 0 ? j.mixdata[0].id : null,
|
||||
};
|
||||
});
|
||||
const MixDataArray = GenerateMixDataArray(
|
||||
inboundRequest,
|
||||
ScaleType,
|
||||
jobHash
|
||||
);
|
||||
|
||||
const MixDataQuery = `
|
||||
mutation UPSERT_MIXDATA{
|
||||
${MixDataArray.map((md, idx) =>
|
||||
GenerateGqlForMixData(md, idx)
|
||||
).join(" ")}
|
||||
}
|
||||
`;
|
||||
|
||||
const resp = await client.request(MixDataQuery);
|
||||
|
||||
//Process the list of ROs and return an object to generate the queries.
|
||||
}
|
||||
});
|
||||
res.sendStatus(200);
|
||||
} catch (error) {
|
||||
res.status(500).JSON(error);
|
||||
logger.log("job-mixdata-upload-error", "ERROR", null, null, {
|
||||
error: error.message,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function DetermineScaleType(inboundRequest) {
|
||||
const ret = { type: "", verson: 0 };
|
||||
|
||||
//PPG Mix Data
|
||||
if (inboundRequest.PPG && inboundRequest.PPG.Header.Protocol.Name === "PPG") {
|
||||
return {
|
||||
type: inboundRequest.PPG.Header.Protocol.Name,
|
||||
company: "PPG",
|
||||
version: inboundRequest.PPG.Header.Protocol.Version,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function GetListOfRos(inboundRequest, ScaleType) {
|
||||
if (ScaleType.company === "PPG" && ScaleType.version === "1.3.0") {
|
||||
return inboundRequest.PPG.DataExportInterface.ROData.RepairOrders.RO.map(
|
||||
(r) => r.RONumber
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function GenerateMixDataArray(inboundRequest, ScaleType, jobHash) {
|
||||
if (ScaleType.company === "PPG" && ScaleType.version === "1.3.0") {
|
||||
return inboundRequest.PPG.DataExportInterface.ROData.RepairOrders.RO.map(
|
||||
(r) => {
|
||||
return {
|
||||
jobid: jobHash[r.RONumber].jobid,
|
||||
id: jobHash[r.RONumber].mixdataid,
|
||||
mixdata: r,
|
||||
totalliquidcost: r.TotalLiquidCost,
|
||||
totalsundrycost: r.TotalSundryCost,
|
||||
company: ScaleType.company,
|
||||
version: ScaleType.version,
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function GenerateGqlForMixData(mixdata, key) {
|
||||
const { id, ...restMixData } = mixdata;
|
||||
|
||||
if (id) {
|
||||
//Update.
|
||||
return `
|
||||
update${key}: update_mixdata_by_pk(pk_columns:{id: "${id}"}, _set: ${JSON.stringify(
|
||||
restMixData
|
||||
).replace(/"(\w+)"\s*:/g, "$1:")}){
|
||||
id
|
||||
}
|
||||
`;
|
||||
} else {
|
||||
//Insert
|
||||
return `
|
||||
insert${key}: insert_mixdata_one(object: ${JSON.stringify(
|
||||
restMixData
|
||||
).replace(/"(\w+)"\s*:/g, "$1:")}){
|
||||
id
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
73
yarn.lock
73
yarn.lock
@@ -548,6 +548,11 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0:
|
||||
dependencies:
|
||||
color-convert "^2.0.1"
|
||||
|
||||
append-field@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/append-field/-/append-field-1.0.0.tgz#1e3440e915f0b1203d23748e78edd7b9b5b43e56"
|
||||
integrity sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY=
|
||||
|
||||
argparse@^1.0.7:
|
||||
version "1.0.10"
|
||||
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
|
||||
@@ -804,6 +809,14 @@ buildcheck@0.0.3:
|
||||
resolved "https://registry.yarnpkg.com/buildcheck/-/buildcheck-0.0.3.tgz#70451897a95d80f7807e68fc412eb2e7e35ff4d5"
|
||||
integrity sha512-pziaA+p/wdVImfcbsZLNF32EiWyujlQLwolMqUQE8xpKNOH7KmZQaY8sXN7DGOEzPAElo9QTaeNRfGnf3iOJbA==
|
||||
|
||||
busboy@^0.2.11:
|
||||
version "0.2.14"
|
||||
resolved "https://registry.yarnpkg.com/busboy/-/busboy-0.2.14.tgz#6c2a622efcf47c57bbbe1e2a9c37ad36c7925453"
|
||||
integrity sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=
|
||||
dependencies:
|
||||
dicer "0.2.5"
|
||||
readable-stream "1.1.x"
|
||||
|
||||
bytes@3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048"
|
||||
@@ -992,7 +1005,7 @@ concat-map@0.0.1:
|
||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
|
||||
|
||||
concat-stream@^1.4.7:
|
||||
concat-stream@^1.4.7, concat-stream@^1.5.2:
|
||||
version "1.6.2"
|
||||
resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34"
|
||||
integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==
|
||||
@@ -1285,6 +1298,14 @@ destroy@~1.0.4:
|
||||
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
|
||||
integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=
|
||||
|
||||
dicer@0.2.5:
|
||||
version "0.2.5"
|
||||
resolved "https://registry.yarnpkg.com/dicer/-/dicer-0.2.5.tgz#5996c086bb33218c812c090bddc09cd12facb70f"
|
||||
integrity sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=
|
||||
dependencies:
|
||||
readable-stream "1.1.x"
|
||||
streamsearch "0.1.2"
|
||||
|
||||
dicer@^0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/dicer/-/dicer-0.3.0.tgz#eacd98b3bfbf92e8ab5c2fdb71aaac44bb06b872"
|
||||
@@ -2853,6 +2874,11 @@ minimist@^1.2.5:
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
|
||||
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
|
||||
|
||||
minimist@^1.2.6:
|
||||
version "1.2.6"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
|
||||
integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
|
||||
|
||||
mkdirp@^0.5.1:
|
||||
version "0.5.5"
|
||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
|
||||
@@ -2860,6 +2886,13 @@ mkdirp@^0.5.1:
|
||||
dependencies:
|
||||
minimist "^1.2.5"
|
||||
|
||||
mkdirp@^0.5.4:
|
||||
version "0.5.6"
|
||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6"
|
||||
integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==
|
||||
dependencies:
|
||||
minimist "^1.2.6"
|
||||
|
||||
moment-timezone@^0.5.34:
|
||||
version "0.5.34"
|
||||
resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.34.tgz#a75938f7476b88f155d3504a9343f7519d9a405c"
|
||||
@@ -2892,6 +2925,20 @@ ms@2.1.3, ms@^2.1.1:
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
|
||||
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
|
||||
|
||||
multer@^1.4.4:
|
||||
version "1.4.4"
|
||||
resolved "https://registry.yarnpkg.com/multer/-/multer-1.4.4.tgz#e2bc6cac0df57a8832b858d7418ccaa8ebaf7d8c"
|
||||
integrity sha512-2wY2+xD4udX612aMqMcB8Ws2Voq6NIUPEtD1be6m411T4uDH/VtL9i//xvcyFlTVfRdaBsk7hV5tgrGQqhuBiw==
|
||||
dependencies:
|
||||
append-field "^1.0.0"
|
||||
busboy "^0.2.11"
|
||||
concat-stream "^1.5.2"
|
||||
mkdirp "^0.5.4"
|
||||
object-assign "^4.1.1"
|
||||
on-finished "^2.3.0"
|
||||
type-is "^1.6.4"
|
||||
xtend "^4.0.0"
|
||||
|
||||
nan@^2.15.0:
|
||||
version "2.15.0"
|
||||
resolved "https://registry.yarnpkg.com/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee"
|
||||
@@ -2975,7 +3022,7 @@ oauth-sign@~0.9.0:
|
||||
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
|
||||
integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
|
||||
|
||||
object-assign@^4:
|
||||
object-assign@^4, object-assign@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
|
||||
@@ -2990,7 +3037,7 @@ object-inspect@^1.9.0:
|
||||
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.11.0.tgz#9dceb146cedd4148a0d9e51ab88d34cf509922b1"
|
||||
integrity sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==
|
||||
|
||||
on-finished@2.4.1:
|
||||
on-finished@2.4.1, on-finished@^2.3.0:
|
||||
version "2.4.1"
|
||||
resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f"
|
||||
integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==
|
||||
@@ -4174,7 +4221,7 @@ type-fest@^0.20.2:
|
||||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4"
|
||||
integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==
|
||||
|
||||
type-is@~1.6.18:
|
||||
type-is@^1.6.4, type-is@~1.6.18:
|
||||
version "1.6.18"
|
||||
resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131"
|
||||
integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==
|
||||
@@ -4409,6 +4456,14 @@ xml2js@0.4.19:
|
||||
sax ">=0.6.0"
|
||||
xmlbuilder "~9.0.1"
|
||||
|
||||
xml2js@^0.4.23:
|
||||
version "0.4.23"
|
||||
resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66"
|
||||
integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==
|
||||
dependencies:
|
||||
sax ">=0.6.0"
|
||||
xmlbuilder "~11.0.0"
|
||||
|
||||
xmlbuilder2@^3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/xmlbuilder2/-/xmlbuilder2-3.0.2.tgz#fc499688b35a916f269e7b459c2fa02bb5c0822a"
|
||||
@@ -4425,6 +4480,11 @@ xmlbuilder@^13.0.2:
|
||||
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-13.0.2.tgz#02ae33614b6a047d1c32b5389c1fdacb2bce47a7"
|
||||
integrity sha512-Eux0i2QdDYKbdbA6AM6xE4m6ZTZr4G4xF9kahI2ukSEMCzwce2eX9WlTI5J3s+NU7hpasFsr8hWIONae7LluAQ==
|
||||
|
||||
xmlbuilder@~11.0.0:
|
||||
version "11.0.1"
|
||||
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3"
|
||||
integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==
|
||||
|
||||
xmlbuilder@~9.0.1:
|
||||
version "9.0.7"
|
||||
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d"
|
||||
@@ -4445,6 +4505,11 @@ xregexp@2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-2.0.0.tgz#52a63e56ca0b84a7f3a5f3d61872f126ad7a5943"
|
||||
integrity sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM=
|
||||
|
||||
xtend@^4.0.0:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
|
||||
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
|
||||
|
||||
y18n@^5.0.5:
|
||||
version "5.0.8"
|
||||
resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55"
|
||||
|
||||
Reference in New Issue
Block a user