Compare commits

...

8 Commits

Author SHA1 Message Date
Allan Carr
4e69fe819e IO-2325 Add in Created by from Action menu 2023-08-18 09:03:13 -07:00
Allan Carr
bf7aa17f65 IO-2325 Shift Clock Created By 2023-08-11 08:35:57 -07:00
Allan Carr
ca129fa4a0 IO-2325 Time Ticket Creation Date 2023-08-10 12:06:47 -07:00
Allan Carr
e69e844568 Merged in release/2023-08-04 (pull request #920)
Release/2023 08 04
2023-08-04 18:06:05 +00:00
Allan Carr
2b5268fb77 Merged in feature/IO-2371-Closing-Period (pull request #918)
IO-2371 Closing Period
2023-08-04 17:35:45 +00:00
Allan Carr
eebe7edba8 IO-2371 Closing period timezone adjustments 2023-08-04 10:36:01 -07:00
Allan Carr
1a5c74dc79 IO-2371 Closing Period 2023-08-04 09:05:03 -07:00
Allan Carr
be62ab5ff9 Merged in feature/IO-2370-Work-In-Progress-Jobs (pull request #916)
IO-2370 Work In Progress Jobs
2023-08-02 23:37:51 +00:00
18 changed files with 248 additions and 37 deletions

View File

@@ -1,6 +1,6 @@
import Icon, { UploadOutlined } from "@ant-design/icons"; import Icon, { UploadOutlined } from "@ant-design/icons";
import { useApolloClient } from "@apollo/client"; import { useApolloClient } from "@apollo/client";
import { MdOpenInNew } from "react-icons/md"; import { useTreatments } from "@splitsoftware/splitio-react";
import { import {
Alert, Alert,
Divider, Divider,
@@ -12,14 +12,17 @@ import {
Switch, Switch,
Upload, Upload,
} from "antd"; } from "antd";
import moment from "moment";
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { MdOpenInNew } from "react-icons/md";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import { createStructuredSelector } from "reselect"; import { createStructuredSelector } from "reselect";
import { CHECK_BILL_INVOICE_NUMBER } from "../../graphql/bills.queries"; import { CHECK_BILL_INVOICE_NUMBER } from "../../graphql/bills.queries";
import { selectBodyshop } from "../../redux/user/user.selectors"; import { selectBodyshop } from "../../redux/user/user.selectors";
import AlertComponent from "../alert/alert.component"; import AlertComponent from "../alert/alert.component";
import BillFormLinesExtended from "../bill-form-lines-extended/bill-form-lines-extended.component";
import FormDatePicker from "../form-date-picker/form-date-picker.component"; import FormDatePicker from "../form-date-picker/form-date-picker.component";
import FormFieldsChanged from "../form-fields-changed-alert/form-fields-changed-alert.component"; import FormFieldsChanged from "../form-fields-changed-alert/form-fields-changed-alert.component";
import CurrencyInput from "../form-items-formatted/currency-form-item.component"; import CurrencyInput from "../form-items-formatted/currency-form-item.component";
@@ -28,8 +31,6 @@ import LayoutFormRow from "../layout-form-row/layout-form-row.component";
import VendorSearchSelect from "../vendor-search-select/vendor-search-select.component"; import VendorSearchSelect from "../vendor-search-select/vendor-search-select.component";
import BillFormLines from "./bill-form.lines.component"; import BillFormLines from "./bill-form.lines.component";
import { CalculateBillTotal } from "./bill-form.totals.utility"; import { CalculateBillTotal } from "./bill-form.totals.utility";
import { useTreatments } from "@splitsoftware/splitio-react";
import BillFormLinesExtended from "../bill-form-lines-extended/bill-form-lines-extended.component";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop, bodyshop: selectBodyshop,
@@ -58,6 +59,11 @@ export function BillFormComponent({
{}, {},
bodyshop.imexshopid bodyshop.imexshopid
); );
const { ClosingPeriod } = useTreatments(
["ClosingPeriod"],
{},
bodyshop.imexshopid
);
const handleVendorSelect = (props, opt) => { const handleVendorSelect = (props, opt) => {
setDiscount(opt.discount); setDiscount(opt.discount);
@@ -259,6 +265,37 @@ export function BillFormComponent({
required: true, required: true,
//message: t("general.validation.required"), //message: t("general.validation.required"),
}, },
({ getFieldValue }) => ({
validator(rule, value) {
if (
ClosingPeriod.treatment === "on" &&
bodyshop.accountingconfig.ClosingPeriod
) {
if (
moment(value)
.startOf("day")
.isSameOrAfter(
moment(
bodyshop.accountingconfig.ClosingPeriod[0]
).startOf("day")
) &&
moment(value)
.startOf("day")
.isSameOrBefore(
moment(
bodyshop.accountingconfig.ClosingPeriod[1]
).endOf("day")
)
) {
return Promise.resolve();
} else {
return Promise.reject(t("bills.validation.closingperiod"));
}
} else {
return Promise.resolve();
}
},
}),
]} ]}
> >
<FormDatePicker disabled={disabled} /> <FormDatePicker disabled={disabled} />

View File

@@ -1,10 +1,9 @@
import { useTreatments } from "@splitsoftware/splitio-react";
import Icon, { import Icon, {
BankFilled, BankFilled,
BarChartOutlined, BarChartOutlined,
CarFilled, CarFilled,
ClockCircleFilled,
CheckCircleOutlined, CheckCircleOutlined,
ClockCircleFilled,
DashboardFilled, DashboardFilled,
DollarCircleFilled, DollarCircleFilled,
ExportOutlined, ExportOutlined,
@@ -26,6 +25,7 @@ import Icon, {
UnorderedListOutlined, UnorderedListOutlined,
UserOutlined, UserOutlined,
} from "@ant-design/icons"; } from "@ant-design/icons";
import { useTreatments } from "@splitsoftware/splitio-react";
import { Layout, Menu } from "antd"; import { Layout, Menu } from "antd";
import React from "react"; import React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
@@ -252,7 +252,11 @@ function Header({
onClick={() => { onClick={() => {
setTimeTicketContext({ setTimeTicketContext({
actions: {}, actions: {},
context: {}, context: {
created_by: currentUser.displayName
? currentUser.email.concat(" | ", currentUser.displayName)
: currentUser.email,
},
}); });
}} }}
> >

View File

@@ -239,7 +239,12 @@ export function JobsDetailHeaderActions({
setTimeTicketContext({ setTimeTicketContext({
actions: {}, actions: {},
context: { jobId: job.id }, context: {
jobId: job.id,
created_by: currentUser.displayName
? currentUser.email.concat(" | ", currentUser.displayName)
: currentUser.email,
},
}); });
}} }}
> >

View File

@@ -1,14 +1,14 @@
import React, { useEffect, useState } from "react"; import { useMutation, useQuery } from "@apollo/client";
import ShopInfoComponent from "./shop-info.component";
import { Form, notification } from "antd"; import { Form, notification } from "antd";
import { useQuery, useMutation } from "@apollo/client"; import moment from "moment";
import { QUERY_BODYSHOP, UPDATE_SHOP } from "../../graphql/bodyshop.queries"; import React, { useEffect, useState } from "react";
import LoadingSpinner from "../loading-spinner/loading-spinner.component";
import AlertComponent from "../alert/alert.component";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { logImEXEvent } from "../../firebase/firebase.utils"; import { logImEXEvent } from "../../firebase/firebase.utils";
import { QUERY_BODYSHOP, UPDATE_SHOP } from "../../graphql/bodyshop.queries";
import AlertComponent from "../alert/alert.component";
import FormsFieldChanged from "../form-fields-changed-alert/form-fields-changed-alert.component"; import FormsFieldChanged from "../form-fields-changed-alert/form-fields-changed-alert.component";
import moment from "moment"; import LoadingSpinner from "../loading-spinner/loading-spinner.component";
import ShopInfoComponent from "./shop-info.component";
export default function ShopInfoContainer() { export default function ShopInfoContainer() {
const [form] = Form.useForm(); const [form] = Form.useForm();
const { t } = useTranslation(); const { t } = useTranslation();
@@ -52,13 +52,28 @@ export default function ShopInfoContainer() {
onFinish={handleFinish} onFinish={handleFinish}
initialValues={ initialValues={
data data
? { ? data.bodyshops[0].accountingconfig.ClosingPeriod
...data.bodyshops[0], ? {
schedule_start_time: moment( ...data.bodyshops[0],
data.bodyshops[0].schedule_start_time accountingconfig: {
), ...data.bodyshops[0].accountingconfig,
schedule_end_time: moment(data.bodyshops[0].schedule_end_time), ClosingPeriod: [
} moment(data.bodyshops[0].accountingconfig.ClosingPeriod[0]),
moment(data.bodyshops[0].accountingconfig.ClosingPeriod[1]),
],
},
schedule_start_time: moment(
data.bodyshops[0].schedule_start_time
),
schedule_end_time: moment(data.bodyshops[0].schedule_end_time),
}
: {
...data.bodyshops[0],
schedule_start_time: moment(
data.bodyshops[0].schedule_start_time
),
schedule_end_time: moment(data.bodyshops[0].schedule_end_time),
}
: null : null
} }
> >

View File

@@ -1,6 +1,8 @@
import { DeleteFilled } from "@ant-design/icons"; import { DeleteFilled } from "@ant-design/icons";
import { useTreatments } from "@splitsoftware/splitio-react";
import { import {
Button, Button,
DatePicker,
Form, Form,
Input, Input,
InputNumber, InputNumber,
@@ -9,8 +11,13 @@ import {
Space, Space,
Switch, Switch,
} from "antd"; } from "antd";
import momentTZ from "moment-timezone";
import React from "react"; import React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../redux/user/user.selectors";
import DatePickerRanges from "../../utils/DatePickerRanges";
import CurrencyInput from "../form-items-formatted/currency-form-item.component"; import CurrencyInput from "../form-items-formatted/currency-form-item.component";
import FormItemEmail from "../form-items-formatted/email-form-item.component"; import FormItemEmail from "../form-items-formatted/email-form-item.component";
import PhoneFormItem, { import PhoneFormItem, {
@@ -18,12 +25,22 @@ import PhoneFormItem, {
} from "../form-items-formatted/phone-form-item.component"; } from "../form-items-formatted/phone-form-item.component";
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component"; import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component";
import LayoutFormRow from "../layout-form-row/layout-form-row.component"; import LayoutFormRow from "../layout-form-row/layout-form-row.component";
import momentTZ from "moment-timezone";
const timeZonesList = momentTZ.tz.names(); const timeZonesList = momentTZ.tz.names();
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
});
const mapDispatchToProps = (dispatch) => ({
//setUserLanguage: language => dispatch(setUserLanguage(language))
});
export default connect(mapStateToProps, mapDispatchToProps)(ShopInfoGeneral);
export default function ShopInfoGeneral({ form }) { export function ShopInfoGeneral({ form, bodyshop }) {
const { t } = useTranslation(); const { t } = useTranslation();
const { ClosingPeriod } = useTreatments(
["ClosingPeriod"],
{},
bodyshop && bodyshop.imexshopid
);
return ( return (
<div> <div>
@@ -392,6 +409,20 @@ export default function ShopInfoGeneral({ form }) {
> >
<Select mode="tags" /> <Select mode="tags" />
</Form.Item> </Form.Item>
{ClosingPeriod.treatment === "on" && (
<>
<Form.Item
allowClear
name={["accountingconfig", "ClosingPeriod"]}
label={t("bodyshop.fields.closingperiod")} //{t("reportcenter.labels.dates")}
>
<DatePicker.RangePicker
format="MM/DD/YYYY"
ranges={DatePickerRanges}
/>
</Form.Item>
</>
)}
</LayoutFormRow> </LayoutFormRow>
<LayoutFormRow <LayoutFormRow
header={t("bodyshop.labels.scoreboardsetup")} header={t("bodyshop.labels.scoreboardsetup")}
@@ -604,7 +635,9 @@ export default function ShopInfoGeneral({ form }) {
</Form.Item> </Form.Item>
<Form.Item <Form.Item
name={["md_email_cc", "parts_return_slip"]} name={["md_email_cc", "parts_return_slip"]}
label={t("bodyshop.fields.md_email_cc", { template: "parts_return_slip" })} label={t("bodyshop.fields.md_email_cc", {
template: "parts_return_slip",
})}
rules={[ rules={[
{ {
//message: t("general.validation.required"), //message: t("general.validation.required"),

View File

@@ -1,21 +1,25 @@
import { useMutation } from "@apollo/client"; import { useMutation } from "@apollo/client";
import { Button, Card, Form, notification, Space } from "antd"; import { Button, Card, Form, notification, Space } from "antd";
import axios from "axios"; import axios from "axios";
import moment from "moment";
import React, { useState } from "react"; import React, { useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { createStructuredSelector } from "reselect"; import { createStructuredSelector } from "reselect";
import { INSERT_NEW_TIME_TICKET } from "../../graphql/timetickets.queries"; import { INSERT_NEW_TIME_TICKET } from "../../graphql/timetickets.queries";
import { selectTechnician } from "../../redux/tech/tech.selectors";
import { selectBodyshop } from "../../redux/user/user.selectors";
import TechClockInComponent from "./tech-job-clock-in-form.component";
import TechJobPrintTickets from "../tech-job-print-tickets/tech-job-print-tickets.component";
import moment from "moment";
import { setModalContext } from "../../redux/modals/modals.actions"; import { setModalContext } from "../../redux/modals/modals.actions";
import { selectTechnician } from "../../redux/tech/tech.selectors";
import {
selectBodyshop,
selectCurrentUser,
} from "../../redux/user/user.selectors";
import TechJobPrintTickets from "../tech-job-print-tickets/tech-job-print-tickets.component";
import TechClockInComponent from "./tech-job-clock-in-form.component";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
technician: selectTechnician, technician: selectTechnician,
bodyshop: selectBodyshop, bodyshop: selectBodyshop,
currentUser: selectCurrentUser,
}); });
const mapDispatchToProps = (dispatch) => ({ const mapDispatchToProps = (dispatch) => ({
setTimeTicketContext: (context) => setTimeTicketContext: (context) =>
@@ -25,6 +29,7 @@ export function TechClockInContainer({
setTimeTicketContext, setTimeTicketContext,
technician, technician,
bodyshop, bodyshop,
currentUser,
}) { }) {
console.log( console.log(
"🚀 ~ file: tech-job-clock-in-form.container.jsx:29 ~ technician:", "🚀 ~ file: tech-job-clock-in-form.container.jsx:29 ~ technician:",
@@ -66,6 +71,12 @@ export function TechClockInContainer({
values.cost_center values.cost_center
); );
}), }),
created_by: currentUser.email.concat(
" | ",
technician.employee_number
.concat(" ", technician.first_name, " ", technician.last_name)
.trim()
),
}, },
], ],
}, },
@@ -100,6 +111,17 @@ export function TechClockInContainer({
employeeid: technician.id, employeeid: technician.id,
flat_rate: emps.flat_rate, flat_rate: emps.flat_rate,
}, },
created_by: currentUser.email.concat(
" | ",
technician.employee_number
.concat(
" ",
technician.first_name,
" ",
technician.last_name
)
.trim()
),
}, },
}); });
}} }}

View File

@@ -9,9 +9,10 @@ import { createStructuredSelector } from "reselect";
import { import {
selectAuthLevel, selectAuthLevel,
selectBodyshop, selectBodyshop,
selectCurrentUser,
} from "../../redux/user/user.selectors"; } from "../../redux/user/user.selectors";
import { onlyUnique } from "../../utils/arrayHelper";
import { DateFormatter, DateTimeFormatter } from "../../utils/DateFormatter"; import { DateFormatter, DateTimeFormatter } from "../../utils/DateFormatter";
import { onlyUnique } from "../../utils/arrayHelper";
import { alphaSort, dateSort } from "../../utils/sorters"; import { alphaSort, dateSort } from "../../utils/sorters";
import RbacWrapper, { import RbacWrapper, {
HasRbacAccess, HasRbacAccess,
@@ -20,6 +21,7 @@ import TimeTicketEnterButton from "../time-ticket-enter-button/time-ticket-enter
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop, bodyshop: selectBodyshop,
authLevel: selectAuthLevel, authLevel: selectAuthLevel,
currentUser: selectCurrentUser,
}); });
const mapDispatchToProps = (dispatch) => ({ const mapDispatchToProps = (dispatch) => ({
//setUserLanguage: language => dispatch(setUserLanguage(language)) //setUserLanguage: language => dispatch(setUserLanguage(language))
@@ -29,6 +31,7 @@ export default connect(mapStateToProps, mapDispatchToProps)(TimeTicketList);
export function TimeTicketList({ export function TimeTicketList({
bodyshop, bodyshop,
authLevel, authLevel,
currentUser,
disabled, disabled,
loading, loading,
timetickets, timetickets,
@@ -193,7 +196,15 @@ export function TimeTicketList({
} }
}, },
}, },
{
title: t("timetickets.fields.created_by"),
dataIndex: "created_by",
key: "created_by",
sorter: (a, b) => alphaSort(a.created_by, b.created_by),
sortOrder:
state.sortedInfo.columnKey === "created_by" && state.sortedInfo.order,
render: (text, record) => record.created_by,
},
{ {
title: t("general.labels.actions"), title: t("general.labels.actions"),
dataIndex: "actions", dataIndex: "actions",
@@ -254,7 +265,12 @@ export function TimeTicketList({
(techConsole ? null : ( (techConsole ? null : (
<TimeTicketEnterButton <TimeTicketEnterButton
actions={{ refetch }} actions={{ refetch }}
context={{ jobId: jobId }} context={{
jobId: jobId,
created_by: currentUser.displayName
? currentUser.email.concat(" | ", currentUser.displayName)
: currentUser.email,
}}
disabled={disabled} disabled={disabled}
> >
{t("timetickets.actions.enter")} {t("timetickets.actions.enter")}

View File

@@ -1,5 +1,5 @@
import { useMutation, useQuery } from "@apollo/client"; import { useMutation, useQuery } from "@apollo/client";
import { Button, Form, Modal, notification, PageHeader, Space } from "antd"; import { Button, Form, Modal, PageHeader, Space, notification } from "antd";
import moment from "moment"; import moment from "moment";
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
@@ -77,6 +77,7 @@ export function TimeTicketModalContainer({
)[0].rate )[0].rate
: null, : null,
bodyshopid: bodyshop.id, bodyshopid: bodyshop.id,
created_by: timeTicketModal.context.created_by,
}, },
], ],
}, },

View File

@@ -65,6 +65,21 @@ export function TimeTicektShiftContainer({
clockon: theTime, clockon: theTime,
date: theTime, date: theTime,
memo: values.memo, memo: values.memo,
created_by: isTechConsole
? currentUser.email.concat(
" | ",
technician.employee_number
.concat(
" ",
technician.first_name,
" ",
technician.last_name
)
.trim()
)
: currentUser.displayName
? currentUser.email.concat(" | ", currentUser.displayName)
: currentUser.email,
}, },
], ],
}, },

View File

@@ -57,6 +57,7 @@ export const GET_LINE_TICKET_BY_PK = gql`
actualhrs actualhrs
ciecacode ciecacode
cost_center cost_center
created_by
date date
id id
jobid jobid

View File

@@ -37,6 +37,7 @@ export const QUERY_TIME_TICKETS_IN_RANGE = gql`
clockon clockon
cost_center cost_center
created_at created_at
created_by
date date
id id
rate rate
@@ -80,6 +81,7 @@ export const QUERY_TIME_TICKETS_TECHNICIAN_IN_RANGE = gql`
clockon clockon
cost_center cost_center
created_at created_at
created_by
date date
id id
rate rate
@@ -112,6 +114,7 @@ export const QUERY_TIME_TICKETS_TECHNICIAN_IN_RANGE = gql`
clockon clockon
cost_center cost_center
created_at created_at
created_by
date date
id id
rate rate
@@ -151,6 +154,7 @@ export const QUERY_TIME_TICKETS_IN_RANGE_SB = gql`
clockon clockon
cost_center cost_center
created_at created_at
created_by
date date
id id
rate rate
@@ -181,6 +185,7 @@ export const QUERY_TIME_TICKETS_IN_RANGE_SB = gql`
clockon clockon
cost_center cost_center
created_at created_at
created_by
date date
id id
rate rate
@@ -210,6 +215,7 @@ export const INSERT_NEW_TIME_TICKET = gql`
insert_timetickets(objects: $timeTicketInput) { insert_timetickets(objects: $timeTicketInput) {
returning { returning {
id id
created_by
clockon clockon
clockoff clockoff
employeeid employeeid

View File

@@ -8,7 +8,6 @@ import {
Form, Form,
Input, Input,
InputNumber, InputNumber,
notification,
PageHeader, PageHeader,
Popconfirm, Popconfirm,
Row, Row,
@@ -17,12 +16,14 @@ import {
Statistic, Statistic,
Switch, Switch,
Typography, Typography,
notification,
} from "antd"; } from "antd";
import React, { useState } from "react"; import React, { useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { connect } from "react-redux"; import { connect } from "react-redux";
//import { useHistory } from "react-router-dom"; //import { useHistory } from "react-router-dom";
import { useTreatments } from "@splitsoftware/splitio-react"; import { useTreatments } from "@splitsoftware/splitio-react";
import Dinero from "dinero.js";
import moment from "moment"; import moment from "moment";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import { createStructuredSelector } from "reselect"; import { createStructuredSelector } from "reselect";
@@ -37,7 +38,6 @@ import { generateJobLinesUpdatesForInvoicing } from "../../graphql/jobs-lines.qu
import { UPDATE_JOB } from "../../graphql/jobs.queries"; import { UPDATE_JOB } from "../../graphql/jobs.queries";
import { selectJobReadOnly } from "../../redux/application/application.selectors"; import { selectJobReadOnly } from "../../redux/application/application.selectors";
import { selectBodyshop } from "../../redux/user/user.selectors"; import { selectBodyshop } from "../../redux/user/user.selectors";
import Dinero from "dinero.js";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop, bodyshop: selectBodyshop,
jobRO: selectJobReadOnly, jobRO: selectJobReadOnly,
@@ -55,6 +55,11 @@ export function JobsCloseComponent({ job, bodyshop, jobRO }) {
{}, {},
bodyshop && bodyshop.imexshopid bodyshop && bodyshop.imexshopid
); );
const { ClosingPeriod } = useTreatments(
["ClosingPeriod"],
{},
bodyshop && bodyshop.imexshopid
);
const handleFinish = async ({ removefromproduction, ...values }) => { const handleFinish = async ({ removefromproduction, ...values }) => {
setLoading(true); setLoading(true);
@@ -254,12 +259,40 @@ export function JobsCloseComponent({ job, bodyshop, jobRO }) {
if (!value || moment(value).isSameOrAfter(moment(), "day")) { if (!value || moment(value).isSameOrAfter(moment(), "day")) {
return Promise.resolve(); return Promise.resolve();
} }
return Promise.reject( return Promise.reject(
new Error(t("jobs.labels.dms.invoicedatefuture")) new Error(t("jobs.labels.dms.invoicedatefuture"))
); );
}, },
}), }),
({ getFieldValue }) => ({
validator(_, value) {
if (
ClosingPeriod.treatment === "on" &&
bodyshop.accountingconfig.ClosingPeriod
) {
if (
moment(value).isSameOrAfter(
moment(
bodyshop.accountingconfig.ClosingPeriod[0]
).startOf("day")
) &&
moment(value).isSameOrBefore(
moment(
bodyshop.accountingconfig.ClosingPeriod[1]
).endOf("day")
)
) {
return Promise.resolve();
} else {
return Promise.reject(
new Error(t("jobs.labels.closingperiod"))
);
}
} else {
return Promise.resolve();
}
},
}),
]} ]}
> >
<DateTimePicker <DateTimePicker

View File

@@ -223,6 +223,7 @@
"reexport": "Bill marked for re-export." "reexport": "Bill marked for re-export."
}, },
"validation": { "validation": {
"closingperiod": "This Bill Date is outside of the Closing Period.",
"inventoryquantity": "Quantity must be greater than or equal to what has been added to inventory ({{number}}).", "inventoryquantity": "Quantity must be greater than or equal to what has been added to inventory ({{number}}).",
"manualinhouse": "Manual posting to the in house vendor is restricted. ", "manualinhouse": "Manual posting to the in house vendor is restricted. ",
"unique_invoice_number": "This invoice number has already been entered for this vendor." "unique_invoice_number": "This invoice number has already been entered for this vendor."
@@ -262,6 +263,7 @@
"bill_local_tax_rate": "Bill - Provincial/State Tax Rate %", "bill_local_tax_rate": "Bill - Provincial/State Tax Rate %",
"bill_state_tax_rate": "Bill - Provincial/State Tax Rate %", "bill_state_tax_rate": "Bill - Provincial/State Tax Rate %",
"city": "City", "city": "City",
"closingperiod": "Closing Period",
"country": "Country", "country": "Country",
"dailybodytarget": "Scoreboard - Daily Body Target", "dailybodytarget": "Scoreboard - Daily Body Target",
"dailypainttarget": "Scoreboard - Daily Paint Target", "dailypainttarget": "Scoreboard - Daily Paint Target",
@@ -1688,6 +1690,7 @@
"checklists": "Checklists", "checklists": "Checklists",
"closeconfirm": "Are you sure you want to close this job? This cannot be easily undone.", "closeconfirm": "Are you sure you want to close this job? This cannot be easily undone.",
"closejob": "Close Job {{ro_number}}", "closejob": "Close Job {{ro_number}}",
"closingperiod": "This Invoice Date is outside of the Closing Period.",
"contracts": "CC Contracts", "contracts": "CC Contracts",
"convertedtolabor": "Lines Converted to Labor", "convertedtolabor": "Lines Converted to Labor",
"cost": "Cost", "cost": "Cost",
@@ -2727,6 +2730,7 @@
"clockon": "Clocked In", "clockon": "Clocked In",
"committed": "", "committed": "",
"cost_center": "Cost Center", "cost_center": "Cost Center",
"created_by": "Created By",
"date": "Ticket Date", "date": "Ticket Date",
"efficiency": "Efficiency", "efficiency": "Efficiency",
"employee": "Employee", "employee": "Employee",

View File

@@ -223,6 +223,7 @@
"reexport": "" "reexport": ""
}, },
"validation": { "validation": {
"closingperiod": "",
"inventoryquantity": "", "inventoryquantity": "",
"manualinhouse": "", "manualinhouse": "",
"unique_invoice_number": "" "unique_invoice_number": ""
@@ -262,6 +263,7 @@
"bill_local_tax_rate": "", "bill_local_tax_rate": "",
"bill_state_tax_rate": "", "bill_state_tax_rate": "",
"city": "", "city": "",
"closingperiod": "",
"country": "", "country": "",
"dailybodytarget": "", "dailybodytarget": "",
"dailypainttarget": "", "dailypainttarget": "",
@@ -1688,6 +1690,7 @@
"checklists": "", "checklists": "",
"closeconfirm": "", "closeconfirm": "",
"closejob": "", "closejob": "",
"closingperiod": "",
"contracts": "", "contracts": "",
"convertedtolabor": "", "convertedtolabor": "",
"cost": "", "cost": "",
@@ -2727,6 +2730,7 @@
"clockon": "", "clockon": "",
"committed": "", "committed": "",
"cost_center": "", "cost_center": "",
"created_by": "",
"date": "", "date": "",
"efficiency": "", "efficiency": "",
"employee": "", "employee": "",

View File

@@ -223,6 +223,7 @@
"reexport": "" "reexport": ""
}, },
"validation": { "validation": {
"closingperiod": "",
"inventoryquantity": "", "inventoryquantity": "",
"manualinhouse": "", "manualinhouse": "",
"unique_invoice_number": "" "unique_invoice_number": ""
@@ -262,6 +263,7 @@
"bill_local_tax_rate": "", "bill_local_tax_rate": "",
"bill_state_tax_rate": "", "bill_state_tax_rate": "",
"city": "", "city": "",
"closingperiod": "",
"country": "", "country": "",
"dailybodytarget": "", "dailybodytarget": "",
"dailypainttarget": "", "dailypainttarget": "",
@@ -1688,6 +1690,7 @@
"checklists": "", "checklists": "",
"closeconfirm": "", "closeconfirm": "",
"closejob": "", "closejob": "",
"closingperiod": "",
"contracts": "", "contracts": "",
"convertedtolabor": "", "convertedtolabor": "",
"cost": "", "cost": "",
@@ -2727,6 +2730,7 @@
"clockon": "", "clockon": "",
"committed": "", "committed": "",
"cost_center": "", "cost_center": "",
"created_by": "",
"date": "", "date": "",
"efficiency": "", "efficiency": "",
"employee": "", "employee": "",

View File

@@ -4649,6 +4649,7 @@
_eq: X-Hasura-User-Id _eq: X-Hasura-User-Id
- active: - active:
_eq: true _eq: true
allow_aggregations: true
update_permissions: update_permissions:
- role: user - role: user
permission: permission:
@@ -4726,6 +4727,7 @@
_eq: X-Hasura-User-Id _eq: X-Hasura-User-Id
- active: - active:
_eq: true _eq: true
allow_aggregations: true
update_permissions: update_permissions:
- role: user - role: user
permission: permission:
@@ -5554,6 +5556,7 @@
- committed_at - committed_at
- cost_center - cost_center
- created_at - created_at
- created_by
- date - date
- employeeid - employeeid
- flat_rate - flat_rate
@@ -5578,6 +5581,7 @@
- committed_at - committed_at
- cost_center - cost_center
- created_at - created_at
- created_by
- date - date
- employeeid - employeeid
- flat_rate - flat_rate
@@ -5611,6 +5615,7 @@
- committed_at - committed_at
- cost_center - cost_center
- created_at - created_at
- created_by
- date - date
- employeeid - employeeid
- flat_rate - flat_rate

View File

@@ -0,0 +1,4 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- alter table "public"."timetickets" add column "created_by" text
-- null;

View File

@@ -0,0 +1,2 @@
alter table "public"."timetickets" add column "created_by" text
null;