Added read only invocies. Removed added reducer coe that was needed BOD-408
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
<babeledit_project version="1.2" be_version="2.7.1">
|
||||
<babeledit_project be_version="2.7.1" version="1.2">
|
||||
<!--
|
||||
|
||||
BabelEdit project file
|
||||
@@ -1567,6 +1567,27 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>exported</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>
|
||||
<concept_node>
|
||||
<name>federal_tax_rate</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
|
||||
@@ -5,7 +5,10 @@ import queryString from "query-string";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import { UPDATE_BILL_LINE } from "../../graphql/bill-lines.queries";
|
||||
import {
|
||||
INSERT_NEW_BILL_LINES,
|
||||
UPDATE_BILL_LINE,
|
||||
} from "../../graphql/bill-lines.queries";
|
||||
import { QUERY_BILL_BY_PK, UPDATE_BILL } from "../../graphql/bills.queries";
|
||||
import AlertComponent from "../alert/alert.component";
|
||||
import BillFormContainer from "../bill-form/bill-form.container";
|
||||
@@ -18,6 +21,7 @@ export default function BillDetailEditcontainer() {
|
||||
const [form] = Form.useForm();
|
||||
const [updateLoading, setUpdateLoading] = useState(false);
|
||||
const [update_bill] = useMutation(UPDATE_BILL);
|
||||
const [insertBillLine] = useMutation(INSERT_NEW_BILL_LINES);
|
||||
const [updateBillLine] = useMutation(UPDATE_BILL_LINE);
|
||||
|
||||
const { loading, error, data, refetch } = useQuery(QUERY_BILL_BY_PK, {
|
||||
@@ -37,17 +41,35 @@ export default function BillDetailEditcontainer() {
|
||||
|
||||
billlines.forEach((il) => {
|
||||
delete il.__typename;
|
||||
updates.push(
|
||||
updateBillLine({
|
||||
variables: {
|
||||
billLineId: il.id,
|
||||
billLine: {
|
||||
...il,
|
||||
joblineid: il.joblineid === "noline" ? null : il.joblineid,
|
||||
|
||||
if (il.id) {
|
||||
updates.push(
|
||||
updateBillLine({
|
||||
variables: {
|
||||
billLineId: il.id,
|
||||
billLine: {
|
||||
...il,
|
||||
joblineid: il.joblineid === "noline" ? null : il.joblineid,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
);
|
||||
})
|
||||
);
|
||||
} else {
|
||||
//It's a new line, have to insert it.
|
||||
updates.push(
|
||||
insertBillLine({
|
||||
variables: {
|
||||
billLines: [
|
||||
{
|
||||
...il,
|
||||
billid: search.billid,
|
||||
joblineid: il.joblineid === "noline" ? null : il.joblineid,
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
await Promise.all(updates);
|
||||
@@ -62,6 +84,9 @@ export default function BillDetailEditcontainer() {
|
||||
|
||||
if (error) return <AlertComponent message={error.message} type="error" />;
|
||||
if (!!!search.billid) return <div>{t("bills.labels.noneselected")}</div>;
|
||||
|
||||
const exported = data && data.bills_by_pk && data.bills_by_pk.exported;
|
||||
|
||||
return (
|
||||
<LoadingSkeleton loading={loading}>
|
||||
<Form
|
||||
@@ -94,10 +119,15 @@ export default function BillDetailEditcontainer() {
|
||||
: {}
|
||||
}
|
||||
>
|
||||
<Button htmlType="submit" loading={updateLoading} type="primary">
|
||||
<Button
|
||||
htmlType="submit"
|
||||
disabled={exported}
|
||||
loading={updateLoading}
|
||||
type="primary"
|
||||
>
|
||||
{t("general.actions.save")}
|
||||
</Button>
|
||||
<BillFormContainer form={form} billEdit />
|
||||
<BillFormContainer form={form} billEdit disabled={exported} />
|
||||
<JobDocumentsGallery
|
||||
jobId={data ? data.bills_by_pk.jobid : null}
|
||||
billId={search.billid}
|
||||
|
||||
@@ -29,6 +29,7 @@ const mapDispatchToProps = (dispatch) => ({});
|
||||
|
||||
export function BillFormComponent({
|
||||
bodyshop,
|
||||
disabled,
|
||||
form,
|
||||
vendorAutoCompleteOptions,
|
||||
lineData,
|
||||
@@ -74,7 +75,7 @@ export function BillFormComponent({
|
||||
]}
|
||||
>
|
||||
<JobSearchSelect
|
||||
disabled={billEdit}
|
||||
disabled={billEdit || disabled}
|
||||
onBlur={() => {
|
||||
if (form.getFieldValue("jobid") !== null) {
|
||||
loadLines({ variables: { id: form.getFieldValue("jobid") } });
|
||||
@@ -94,6 +95,7 @@ export function BillFormComponent({
|
||||
]}
|
||||
>
|
||||
<VendorSearchSelect
|
||||
disabled={disabled}
|
||||
options={vendorAutoCompleteOptions}
|
||||
onSelect={handleVendorSelect}
|
||||
/>
|
||||
@@ -111,7 +113,7 @@ export function BillFormComponent({
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input />
|
||||
<Input disabled={disabled} />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={t("bills.fields.date")}
|
||||
@@ -123,7 +125,7 @@ export function BillFormComponent({
|
||||
},
|
||||
]}
|
||||
>
|
||||
<FormDatePicker />
|
||||
<FormDatePicker disabled={disabled} />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={t("bills.fields.is_credit_memo")}
|
||||
@@ -142,19 +144,19 @@ export function BillFormComponent({
|
||||
},
|
||||
]}
|
||||
>
|
||||
<CurrencyInput min={0} />
|
||||
<CurrencyInput min={0} disabled={disabled} />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={t("bills.fields.federal_tax_rate")}
|
||||
name="federal_tax_rate"
|
||||
>
|
||||
<CurrencyInput min={0} />
|
||||
<CurrencyInput min={0} disabled={disabled} />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={t("bills.fields.state_tax_rate")}
|
||||
name="state_tax_rate"
|
||||
>
|
||||
<CurrencyInput min={0} />
|
||||
<CurrencyInput min={0} disabled={disabled} />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={t("bills.fields.local_tax_rate")}
|
||||
@@ -164,7 +166,7 @@ export function BillFormComponent({
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item label={t("bills.fields.allpartslocation")} name="location">
|
||||
<Select style={{ width: "10rem" }}>
|
||||
<Select style={{ width: "10rem" }} disabled={disabled}>
|
||||
{bodyshop.md_parts_locations.map((loc, idx) => (
|
||||
<Select.Option key={idx} value={loc}>
|
||||
{loc}
|
||||
@@ -181,6 +183,7 @@ export function BillFormComponent({
|
||||
discount={discount}
|
||||
form={form}
|
||||
responsibilityCenters={responsibilityCenters}
|
||||
disabled={disabled}
|
||||
/>
|
||||
|
||||
<Form.Item
|
||||
|
||||
@@ -11,7 +11,7 @@ const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop,
|
||||
});
|
||||
|
||||
export function BillFormContainer({ bodyshop, form, billEdit }) {
|
||||
export function BillFormContainer({ bodyshop, form, billEdit, disabled }) {
|
||||
const { data: VendorAutoCompleteData } = useQuery(SEARCH_VENDOR_AUTOCOMPLETE);
|
||||
|
||||
const [loadLines, { data: lineData }] = useLazyQuery(
|
||||
@@ -19,18 +19,17 @@ export function BillFormContainer({ bodyshop, form, billEdit }) {
|
||||
);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<BillFormComponent
|
||||
form={form}
|
||||
billEdit={billEdit}
|
||||
vendorAutoCompleteOptions={
|
||||
VendorAutoCompleteData && VendorAutoCompleteData.vendors
|
||||
}
|
||||
loadLines={loadLines}
|
||||
lineData={lineData ? lineData.joblines : []}
|
||||
responsibilityCenters={bodyshop.md_responsibility_centers || null}
|
||||
/>
|
||||
</div>
|
||||
<BillFormComponent
|
||||
disabled={disabled}
|
||||
form={form}
|
||||
billEdit={billEdit}
|
||||
vendorAutoCompleteOptions={
|
||||
VendorAutoCompleteData && VendorAutoCompleteData.vendors
|
||||
}
|
||||
loadLines={loadLines}
|
||||
lineData={lineData ? lineData.joblines : []}
|
||||
responsibilityCenters={bodyshop.md_responsibility_centers || null}
|
||||
/>
|
||||
);
|
||||
}
|
||||
export default connect(mapStateToProps, null)(BillFormContainer);
|
||||
|
||||
@@ -15,6 +15,7 @@ import BillLineSearchSelect from "../bill-line-search-select/bill-line-search-se
|
||||
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component";
|
||||
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
||||
export default function BillEnterModalLinesComponent({
|
||||
disabled,
|
||||
lineData,
|
||||
discount,
|
||||
form,
|
||||
@@ -45,6 +46,7 @@ export default function BillEnterModalLinesComponent({
|
||||
]}
|
||||
>
|
||||
<BillLineSearchSelect
|
||||
disabled={disabled}
|
||||
options={lineData}
|
||||
onSelect={(value, opt) => {
|
||||
setFieldsValue({
|
||||
@@ -82,7 +84,7 @@ export default function BillEnterModalLinesComponent({
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input />
|
||||
<Input disabled={disabled} />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={t("billlines.fields.quantity")}
|
||||
@@ -95,7 +97,11 @@ export default function BillEnterModalLinesComponent({
|
||||
},
|
||||
]}
|
||||
>
|
||||
<InputNumber precision={0} min={0} />
|
||||
<InputNumber
|
||||
precision={0}
|
||||
min={0}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={t("billlines.fields.actual")}
|
||||
@@ -110,6 +116,7 @@ export default function BillEnterModalLinesComponent({
|
||||
>
|
||||
<CurrencyInput
|
||||
min={0}
|
||||
disabled={disabled}
|
||||
onBlur={(e) => {
|
||||
setFieldsValue({
|
||||
billlines: getFieldsValue(
|
||||
@@ -141,7 +148,7 @@ export default function BillEnterModalLinesComponent({
|
||||
},
|
||||
]}
|
||||
>
|
||||
<CurrencyInput min={0} />
|
||||
<CurrencyInput min={0} disabled={disabled} />
|
||||
</Form.Item>
|
||||
<Form.Item shouldUpdate>
|
||||
{() => {
|
||||
@@ -172,7 +179,7 @@ export default function BillEnterModalLinesComponent({
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Select style={{ width: "150px" }}>
|
||||
<Select style={{ width: "150px" }} disabled={disabled}>
|
||||
{responsibilityCenters.costs.map((item) => (
|
||||
<Select.Option key={item.name}>
|
||||
{item.name}
|
||||
@@ -187,7 +194,7 @@ export default function BillEnterModalLinesComponent({
|
||||
valuePropName="checked"
|
||||
name={[field.name, "applicable_taxes", "federal"]}
|
||||
>
|
||||
<Switch />
|
||||
<Switch disabled={disabled} />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={t("billlines.fields.state_tax_applicable")}
|
||||
@@ -195,7 +202,7 @@ export default function BillEnterModalLinesComponent({
|
||||
valuePropName="checked"
|
||||
name={[field.name, "applicable_taxes", "state"]}
|
||||
>
|
||||
<Switch />
|
||||
<Switch disabled={disabled} />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={t("billlines.fields.local_tax_applicable")}
|
||||
@@ -203,7 +210,7 @@ export default function BillEnterModalLinesComponent({
|
||||
valuePropName="checked"
|
||||
name={[field.name, "applicable_taxes", "local"]}
|
||||
>
|
||||
<Switch />
|
||||
<Switch disabled={disabled} />
|
||||
</Form.Item>
|
||||
</LayoutFormRow>
|
||||
<FormListMoveArrows
|
||||
@@ -212,6 +219,7 @@ export default function BillEnterModalLinesComponent({
|
||||
total={fields.length}
|
||||
/>
|
||||
<DeleteFilled
|
||||
disabled={disabled}
|
||||
onClick={() => {
|
||||
remove(field.name);
|
||||
}}
|
||||
@@ -223,6 +231,7 @@ export default function BillEnterModalLinesComponent({
|
||||
))}
|
||||
<Form.Item>
|
||||
<Button
|
||||
disabled={disabled}
|
||||
onClick={() => {
|
||||
add();
|
||||
}}
|
||||
|
||||
@@ -6,7 +6,7 @@ import CurrencyFormatter from "../../utils/CurrencyFormatter";
|
||||
//To be used as a form element only.
|
||||
const { Option } = Select;
|
||||
const BillLineSearchSelect = (
|
||||
{ value, onChange, options, onBlur, onSelect },
|
||||
{ value, onChange, options, onBlur, onSelect, disabled },
|
||||
ref
|
||||
) => {
|
||||
const [option, setOption] = useState(value);
|
||||
@@ -20,6 +20,7 @@ const BillLineSearchSelect = (
|
||||
|
||||
return (
|
||||
<Select
|
||||
disabled={disabled}
|
||||
ref={ref}
|
||||
showSearch
|
||||
autoFocus
|
||||
|
||||
@@ -13,7 +13,7 @@ import { DateFormatter } from "../../utils/DateFormatter";
|
||||
import { alphaSort } from "../../utils/sorters";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
jobRO: selectJobReadOnly,
|
||||
//jobRO: selectJobReadOnly,
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
@@ -26,7 +26,6 @@ const mapDispatchToProps = (dispatch) => ({
|
||||
});
|
||||
|
||||
export function BillsListTableComponent({
|
||||
jobRO,
|
||||
job,
|
||||
billsQuery,
|
||||
handleOnRowClick,
|
||||
@@ -94,13 +93,22 @@ export function BillsListTableComponent({
|
||||
state.sortedInfo.order,
|
||||
render: (text, record) => <Checkbox checked={record.is_credit_memo} />,
|
||||
},
|
||||
{
|
||||
title: t("bills.fields.exported"),
|
||||
dataIndex: "exported",
|
||||
key: "exported",
|
||||
sorter: (a, b) => a.exported - b.exported,
|
||||
sortOrder:
|
||||
state.sortedInfo.columnKey === "exported" && state.sortedInfo.order,
|
||||
render: (text, record) => <Checkbox checked={record.exported} />,
|
||||
},
|
||||
{
|
||||
title: t("general.labels.actions"),
|
||||
dataIndex: "actions",
|
||||
key: "actions",
|
||||
render: (text, record) => (
|
||||
<div>
|
||||
{jobRO ? (
|
||||
{record.exported ? (
|
||||
<Button disabled>{t("bills.actions.edit")}</Button>
|
||||
) : (
|
||||
<Link
|
||||
@@ -237,7 +245,7 @@ export function BillsListTableComponent({
|
||||
</Descriptions.Item>
|
||||
</Descriptions>
|
||||
<Button
|
||||
disabled={record.is_credit_memo || jobRO}
|
||||
disabled={record.is_credit_memo || record.exported}
|
||||
onClick={() =>
|
||||
setPartsOrderContext({
|
||||
actions: {},
|
||||
@@ -302,7 +310,6 @@ export function BillsListTableComponent({
|
||||
{job ? (
|
||||
<div>
|
||||
<Button
|
||||
disabled={jobRO}
|
||||
onClick={() => {
|
||||
setBillEnterContext({
|
||||
actions: { refetch: billsQuery.refetch },
|
||||
|
||||
@@ -12,3 +12,13 @@ export const UPDATE_BILL_LINE = gql`
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const INSERT_NEW_BILL_LINES = gql`
|
||||
mutation INSERT_NEW_BILL_LINES($billLines: [billlines_insert_input!]!) {
|
||||
insert_billlines(objects: $billLines) {
|
||||
returning {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -35,6 +35,7 @@ export const QUERY_ALL_BILLS_PAGINATED = gql`
|
||||
total
|
||||
invoice_number
|
||||
date
|
||||
exported
|
||||
job {
|
||||
id
|
||||
ro_number
|
||||
@@ -69,6 +70,7 @@ export const QUERY_BILLS_BY_JOBID = gql`
|
||||
}
|
||||
order_date
|
||||
deliver_by
|
||||
exported
|
||||
parts_order_lines {
|
||||
id
|
||||
act_price
|
||||
|
||||
@@ -80,7 +80,18 @@ export function BillsListPage({
|
||||
sortOrder:
|
||||
state.sortedInfo.columnKey === "is_credit_memo" &&
|
||||
state.sortedInfo.order,
|
||||
render: (text, record) => <Checkbox checked={record.is_credit_memo} />,
|
||||
render: (text, record) => (
|
||||
<Checkbox disabled checked={record.is_credit_memo} />
|
||||
),
|
||||
},
|
||||
{
|
||||
title: t("bills.fields.exported"),
|
||||
dataIndex: "exported",
|
||||
key: "exported",
|
||||
sorter: (a, b) => a.exported - b.exported,
|
||||
sortOrder:
|
||||
state.sortedInfo.columnKey === "exported" && state.sortedInfo.order,
|
||||
render: (text, record) => <Checkbox disabled checked={record.exported} />,
|
||||
},
|
||||
{
|
||||
title: t("general.labels.actions"),
|
||||
|
||||
@@ -43,8 +43,3 @@ export const setJobReadOnly = (bool) => ({
|
||||
type: ApplicationActionTypes.SET_JOB_READONLY,
|
||||
payload: bool,
|
||||
});
|
||||
|
||||
export const setBillReadOnly = (bool) => ({
|
||||
type: ApplicationActionTypes.SET_BILL_READONLY,
|
||||
payload: bool,
|
||||
});
|
||||
|
||||
@@ -11,7 +11,6 @@ const INITIAL_STATE = {
|
||||
error: null,
|
||||
},
|
||||
jobReadOnly: false,
|
||||
billReadOnly: false,
|
||||
};
|
||||
|
||||
const applicationReducer = (state = INITIAL_STATE, action) => {
|
||||
@@ -65,8 +64,6 @@ const applicationReducer = (state = INITIAL_STATE, action) => {
|
||||
loading: false,
|
||||
};
|
||||
|
||||
case ApplicationActionTypes.SET_BILL_READONLY:
|
||||
return { ...state, billReadOnly: action.payload };
|
||||
case ApplicationActionTypes.SET_JOB_READONLY:
|
||||
return { ...state, jobReadOnly: action.payload };
|
||||
|
||||
|
||||
@@ -36,8 +36,3 @@ export const selectJobReadOnly = createSelector(
|
||||
[selectApplication],
|
||||
(application) => application.jobReadOnly
|
||||
);
|
||||
|
||||
export const selectBillReadOnly = createSelector(
|
||||
[selectApplication],
|
||||
(application) => application.billReadOnly
|
||||
);
|
||||
|
||||
@@ -8,6 +8,5 @@ const ApplicationActionTypes = {
|
||||
ADD_RECENT_ITEM: "ADD_RECENT_ITEM",
|
||||
SET_SELECTED_HEADER: "SET_SELECTED_HEADER",
|
||||
SET_JOB_READONLY: "SET_JOB_READONLY",
|
||||
SET_BILL_READONLY: "SET_BILL_READONLY",
|
||||
};
|
||||
export default ApplicationActionTypes;
|
||||
|
||||
@@ -116,6 +116,7 @@
|
||||
"fields": {
|
||||
"allpartslocation": "Parts Bin",
|
||||
"date": "Bill Date",
|
||||
"exported": "Exported",
|
||||
"federal_tax_rate": "Federal Tax Rate",
|
||||
"invoice_number": "Invoice Number",
|
||||
"is_credit_memo": "Credit Memo?",
|
||||
|
||||
@@ -116,6 +116,7 @@
|
||||
"fields": {
|
||||
"allpartslocation": "",
|
||||
"date": "",
|
||||
"exported": "",
|
||||
"federal_tax_rate": "",
|
||||
"invoice_number": "",
|
||||
"is_credit_memo": "",
|
||||
|
||||
@@ -116,6 +116,7 @@
|
||||
"fields": {
|
||||
"allpartslocation": "",
|
||||
"date": "",
|
||||
"exported": "",
|
||||
"federal_tax_rate": "",
|
||||
"invoice_number": "",
|
||||
"is_credit_memo": "",
|
||||
|
||||
Reference in New Issue
Block a user