Added error handling for receivables screen BOD-138
This commit is contained in:
@@ -7610,6 +7610,48 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>exporting</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>exporting-partner</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>
|
<concept_node>
|
||||||
<name>invoicing</name>
|
<name>invoicing</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -11604,6 +11646,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</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>
|
<concept_node>
|
||||||
<name>invoiced</name>
|
<name>invoiced</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -11787,6 +11850,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>accounting-receivables</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>
|
<concept_node>
|
||||||
<name>activejobs</name>
|
<name>activejobs</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -14834,6 +14918,27 @@
|
|||||||
<folder_node>
|
<folder_node>
|
||||||
<name>titles</name>
|
<name>titles</name>
|
||||||
<children>
|
<children>
|
||||||
|
<concept_node>
|
||||||
|
<name>accounting-receivables</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>
|
<concept_node>
|
||||||
<name>app</name>
|
<name>app</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -14858,6 +14963,27 @@
|
|||||||
<folder_node>
|
<folder_node>
|
||||||
<name>bc</name>
|
<name>bc</name>
|
||||||
<children>
|
<children>
|
||||||
|
<concept_node>
|
||||||
|
<name>accounting-receivables</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>
|
<concept_node>
|
||||||
<name>availablejobs</name>
|
<name>availablejobs</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
|
|||||||
@@ -0,0 +1,197 @@
|
|||||||
|
import { Input, Table } from "antd";
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
import CurrencyFormatter from "../../utils/CurrencyFormatter";
|
||||||
|
import { alphaSort } from "../../utils/sorters";
|
||||||
|
import JobExportButton from "../jobs-close-export-button/jobs-close-export-button.component";
|
||||||
|
|
||||||
|
export default function AccountingReceivablesTableComponent({ loading, jobs }) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const [state, setState] = useState({
|
||||||
|
sortedInfo: {},
|
||||||
|
search: "",
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleTableChange = (pagination, filters, sorter) => {
|
||||||
|
setState({ ...state, filteredInfo: filters, sortedInfo: sorter });
|
||||||
|
};
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
title: t("jobs.fields.ro_number"),
|
||||||
|
dataIndex: "ro_number",
|
||||||
|
key: "ro_number",
|
||||||
|
sorter: (a, b) => alphaSort(a.ro_number, b.ro_number),
|
||||||
|
sortOrder:
|
||||||
|
state.sortedInfo.columnKey === "ro_number" && state.sortedInfo.order,
|
||||||
|
render: (text, record) => (
|
||||||
|
<Link to={"/manage/jobs/" + record.id}>{record.ro_number}</Link>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t("jobs.fields.est_number"),
|
||||||
|
dataIndex: "est_number",
|
||||||
|
key: "est_number",
|
||||||
|
sorter: (a, b) => a.est_number - b.est_number,
|
||||||
|
sortOrder:
|
||||||
|
state.sortedInfo.columnKey === "est_number" && state.sortedInfo.order,
|
||||||
|
render: (text, record) => (
|
||||||
|
<Link to={"/manage/jobs/" + record.id}>{record.est_number}</Link>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t("jobs.fields.status"),
|
||||||
|
dataIndex: "status",
|
||||||
|
key: "status",
|
||||||
|
sorter: (a, b) => a.status - b.status,
|
||||||
|
sortOrder:
|
||||||
|
state.sortedInfo.columnKey === "status" && state.sortedInfo.order,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t("jobs.fields.owner"),
|
||||||
|
dataIndex: "owner",
|
||||||
|
key: "owner",
|
||||||
|
sorter: (a, b) => alphaSort(a.ownr_ln, b.ownr_ln),
|
||||||
|
sortOrder:
|
||||||
|
state.sortedInfo.columnKey === "owner" && state.sortedInfo.order,
|
||||||
|
render: (text, record) => {
|
||||||
|
return record.owner ? (
|
||||||
|
<Link to={"/manage/owners/" + record.owner.id}>
|
||||||
|
{`${record.ownr_fn || ""} ${record.ownr_ln || ""}`}
|
||||||
|
</Link>
|
||||||
|
) : (
|
||||||
|
<span>{`${record.ownr_fn || ""} ${record.ownr_ln || ""}`}</span>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t("jobs.fields.vehicle"),
|
||||||
|
dataIndex: "vehicle",
|
||||||
|
key: "vehicle",
|
||||||
|
ellipsis: true,
|
||||||
|
render: (text, record) => {
|
||||||
|
return record.vehicleid ? (
|
||||||
|
<Link to={"/manage/vehicles/" + record.vehicleid}>
|
||||||
|
{`${record.v_model_yr || ""} ${record.v_make_desc || ""} ${
|
||||||
|
record.v_model_desc || ""
|
||||||
|
}`}
|
||||||
|
</Link>
|
||||||
|
) : (
|
||||||
|
<span>{`${record.v_model_yr || ""} ${record.v_make_desc || ""} ${
|
||||||
|
record.v_model_desc || ""
|
||||||
|
}`}</span>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t("jobs.fields.clm_no"),
|
||||||
|
dataIndex: "clm_no",
|
||||||
|
key: "clm_no",
|
||||||
|
ellipsis: true,
|
||||||
|
sorter: (a, b) => alphaSort(a.clm_no, b.clm_no),
|
||||||
|
sortOrder:
|
||||||
|
state.sortedInfo.columnKey === "clm_no" && state.sortedInfo.order,
|
||||||
|
render: (text, record) => {
|
||||||
|
return record.clm_no ? (
|
||||||
|
<span>{record.clm_no}</span>
|
||||||
|
) : (
|
||||||
|
t("general.labels.unknown")
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t("jobs.fields.clm_total"),
|
||||||
|
dataIndex: "clm_total",
|
||||||
|
key: "clm_total",
|
||||||
|
sorter: (a, b) => a.clm_total - b.clm_total,
|
||||||
|
sortOrder:
|
||||||
|
state.sortedInfo.columnKey === "clm_total" && state.sortedInfo.order,
|
||||||
|
render: (text, record) => {
|
||||||
|
return record.clm_total ? (
|
||||||
|
<CurrencyFormatter>{record.clm_total}</CurrencyFormatter>
|
||||||
|
) : (
|
||||||
|
t("general.labels.unknown")
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t("general.labels.actions"),
|
||||||
|
dataIndex: "actions",
|
||||||
|
key: "actions",
|
||||||
|
sorter: (a, b) => a.clm_total - b.clm_total,
|
||||||
|
|
||||||
|
render: (text, record) => (
|
||||||
|
<div>
|
||||||
|
<JobExportButton
|
||||||
|
jobId={record.id}
|
||||||
|
disabled={!!record.date_exported}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{JSON.stringify(record.date_exported)}
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const handleSearch = (e) => {
|
||||||
|
setState({ ...state, search: e.target.value });
|
||||||
|
};
|
||||||
|
|
||||||
|
const dataSource = state.search
|
||||||
|
? jobs.filter(
|
||||||
|
(v) =>
|
||||||
|
(v.ro_number || "")
|
||||||
|
.toString()
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(state.search.toLowerCase()) ||
|
||||||
|
(v.est_number || "")
|
||||||
|
.toString()
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(state.search.toLowerCase()) ||
|
||||||
|
(v.ownr_fn || "")
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(state.search.toLowerCase()) ||
|
||||||
|
(v.ownr_ln || "")
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(state.search.toLowerCase()) ||
|
||||||
|
(v.ownr_co_nm || "")
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(state.search.toLowerCase()) ||
|
||||||
|
(v.v_model_desc || "")
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(state.search.toLowerCase()) ||
|
||||||
|
(v.v_make_desc || "")
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(state.search.toLowerCase()) ||
|
||||||
|
(v.clm_no || "").toLowerCase().includes(state.search.toLowerCase())
|
||||||
|
)
|
||||||
|
: jobs;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Table
|
||||||
|
loading={loading}
|
||||||
|
title={() => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Input
|
||||||
|
value={state.search}
|
||||||
|
onChange={handleSearch}
|
||||||
|
placeholder={t("general.labels.search")}
|
||||||
|
allowClear
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
dataSource={dataSource}
|
||||||
|
size="small"
|
||||||
|
pagination={{ position: "top" }}
|
||||||
|
columns={columns}
|
||||||
|
rowKey="id"
|
||||||
|
onChange={handleTableChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -42,28 +42,29 @@ function Header({
|
|||||||
//TODO Add
|
//TODO Add
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Row type='flex' justify='space-around' align='middle'>
|
<Row type="flex" justify="space-around" align="middle">
|
||||||
{logo ? (
|
{logo ? (
|
||||||
<Col span={3}>
|
<Col span={3}>
|
||||||
<img alt='Shop Logo' src={logo} style={{ height: "40px" }} />
|
<img alt="Shop Logo" src={logo} style={{ height: "40px" }} />
|
||||||
</Col>
|
</Col>
|
||||||
) : null}
|
) : null}
|
||||||
<Col span={21}>
|
<Col span={21}>
|
||||||
{landingHeader ? (
|
{landingHeader ? (
|
||||||
<Menu
|
<Menu
|
||||||
theme='dark'
|
theme="dark"
|
||||||
className='header'
|
className="header"
|
||||||
selectedKeys={selectedNavItem}
|
selectedKeys={selectedNavItem}
|
||||||
mode='horizontal'
|
mode="horizontal"
|
||||||
onClick={handleMenuClick}>
|
onClick={handleMenuClick}
|
||||||
|
>
|
||||||
<ManageSignInButton />
|
<ManageSignInButton />
|
||||||
|
|
||||||
<Menu.SubMenu
|
<Menu.SubMenu
|
||||||
title={
|
title={
|
||||||
<div>
|
<div>
|
||||||
<Avatar
|
<Avatar
|
||||||
size='medium'
|
size="medium"
|
||||||
alt='Avatar'
|
alt="Avatar"
|
||||||
src={
|
src={
|
||||||
currentUser.photoURL ? currentUser.photoURL : UserImage
|
currentUser.photoURL ? currentUser.photoURL : UserImage
|
||||||
}
|
}
|
||||||
@@ -71,12 +72,13 @@ function Header({
|
|||||||
/>
|
/>
|
||||||
{currentUser.displayName || t("general.labels.unknown")}
|
{currentUser.displayName || t("general.labels.unknown")}
|
||||||
</div>
|
</div>
|
||||||
}>
|
}
|
||||||
|
>
|
||||||
<Menu.Item onClick={() => signOutStart()}>
|
<Menu.Item onClick={() => signOutStart()}>
|
||||||
{t("user.actions.signout")}
|
{t("user.actions.signout")}
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item>
|
<Menu.Item>
|
||||||
<Link to='/manage/profile'>
|
<Link to="/manage/profile">
|
||||||
{t("menus.currentuser.profile")}
|
{t("menus.currentuser.profile")}
|
||||||
</Link>
|
</Link>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
@@ -86,14 +88,15 @@ function Header({
|
|||||||
<GlobalOutlined />
|
<GlobalOutlined />
|
||||||
<span>{t("menus.currentuser.languageselector")}</span>
|
<span>{t("menus.currentuser.languageselector")}</span>
|
||||||
</span>
|
</span>
|
||||||
}>
|
}
|
||||||
<Menu.Item actiontype='lang-select' key='en-US'>
|
>
|
||||||
|
<Menu.Item actiontype="lang-select" key="en-US">
|
||||||
{t("general.languages.english")}
|
{t("general.languages.english")}
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item actiontype='lang-select' key='fr-CA'>
|
<Menu.Item actiontype="lang-select" key="fr-CA">
|
||||||
{t("general.languages.french")}
|
{t("general.languages.french")}
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item actiontype='lang-select' key='es-MX'>
|
<Menu.Item actiontype="lang-select" key="es-MX">
|
||||||
{t("general.languages.spanish")}
|
{t("general.languages.spanish")}
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
</Menu.SubMenu>
|
</Menu.SubMenu>
|
||||||
@@ -101,13 +104,14 @@ function Header({
|
|||||||
</Menu>
|
</Menu>
|
||||||
) : (
|
) : (
|
||||||
<Menu
|
<Menu
|
||||||
theme='dark'
|
theme="dark"
|
||||||
className='header'
|
className="header"
|
||||||
selectedKeys={selectedNavItem}
|
selectedKeys={selectedNavItem}
|
||||||
mode='horizontal'
|
mode="horizontal"
|
||||||
onClick={handleMenuClick}>
|
onClick={handleMenuClick}
|
||||||
<Menu.Item key='home'>
|
>
|
||||||
<Link to='/manage'>
|
<Menu.Item key="home">
|
||||||
|
<Link to="/manage">
|
||||||
<HomeFilled />
|
<HomeFilled />
|
||||||
{t("menus.header.home")}
|
{t("menus.header.home")}
|
||||||
</Link>
|
</Link>
|
||||||
@@ -118,40 +122,41 @@ function Header({
|
|||||||
<Icon component={FaCarCrash} />
|
<Icon component={FaCarCrash} />
|
||||||
<span>{t("menus.header.jobs")}</span>
|
<span>{t("menus.header.jobs")}</span>
|
||||||
</span>
|
</span>
|
||||||
}>
|
}
|
||||||
<Menu.Item key='schedule'>
|
>
|
||||||
<Link to='/manage/schedule'>
|
<Menu.Item key="schedule">
|
||||||
|
<Link to="/manage/schedule">
|
||||||
<Icon component={FaCalendarAlt} />
|
<Icon component={FaCalendarAlt} />
|
||||||
{t("menus.header.schedule")}
|
{t("menus.header.schedule")}
|
||||||
</Link>
|
</Link>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item key='production'>
|
<Menu.Item key="production">
|
||||||
<Link to='/manage/production/list'>
|
<Link to="/manage/production/list">
|
||||||
<Icon component={FaCalendarAlt} />
|
<Icon component={FaCalendarAlt} />
|
||||||
{t("menus.header.productionlist")}
|
{t("menus.header.productionlist")}
|
||||||
</Link>
|
</Link>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item key='activejobs'>
|
<Menu.Item key="activejobs">
|
||||||
<Link to='/manage/jobs'>{t("menus.header.activejobs")}</Link>
|
<Link to="/manage/jobs">{t("menus.header.activejobs")}</Link>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item key='alljobs'>
|
<Menu.Item key="alljobs">
|
||||||
<Link to='/manage/jobs/all'>{t("menus.header.alljobs")}</Link>
|
<Link to="/manage/jobs/all">{t("menus.header.alljobs")}</Link>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item key='availablejobs'>
|
<Menu.Item key="availablejobs">
|
||||||
<Link to='/manage/available'>
|
<Link to="/manage/available">
|
||||||
{t("menus.header.availablejobs")}
|
{t("menus.header.availablejobs")}
|
||||||
</Link>
|
</Link>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
</Menu.SubMenu>
|
</Menu.SubMenu>
|
||||||
<Menu.SubMenu title={t("menus.header.customers")}>
|
<Menu.SubMenu title={t("menus.header.customers")}>
|
||||||
<Menu.Item key='owners'>
|
<Menu.Item key="owners">
|
||||||
<Link to='/manage/owners'>
|
<Link to="/manage/owners">
|
||||||
<TeamOutlined />
|
<TeamOutlined />
|
||||||
{t("menus.header.owners")}
|
{t("menus.header.owners")}
|
||||||
</Link>
|
</Link>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item key='vehicles'>
|
<Menu.Item key="vehicles">
|
||||||
<Link to='/manage/vehicles'>
|
<Link to="/manage/vehicles">
|
||||||
<CarFilled />
|
<CarFilled />
|
||||||
{t("menus.header.vehicles")}
|
{t("menus.header.vehicles")}
|
||||||
</Link>
|
</Link>
|
||||||
@@ -164,21 +169,22 @@ function Header({
|
|||||||
<CarFilled />
|
<CarFilled />
|
||||||
<span>{t("menus.header.courtesycars")}</span>
|
<span>{t("menus.header.courtesycars")}</span>
|
||||||
</span>
|
</span>
|
||||||
}>
|
}
|
||||||
<Menu.Item key='courtesycarsall'>
|
>
|
||||||
<Link to='/manage/courtesycars'>
|
<Menu.Item key="courtesycarsall">
|
||||||
|
<Link to="/manage/courtesycars">
|
||||||
<CarFilled />
|
<CarFilled />
|
||||||
{t("menus.header.courtesycars-all")}
|
{t("menus.header.courtesycars-all")}
|
||||||
</Link>
|
</Link>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item key='contracts'>
|
<Menu.Item key="contracts">
|
||||||
<Link to='/manage/courtesycars/contracts'>
|
<Link to="/manage/courtesycars/contracts">
|
||||||
<FileFilled />
|
<FileFilled />
|
||||||
{t("menus.header.courtesycars-contracts")}
|
{t("menus.header.courtesycars-contracts")}
|
||||||
</Link>
|
</Link>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item key='newcontract'>
|
<Menu.Item key="newcontract">
|
||||||
<Link to='/manage/courtesycars/contracts/new'>
|
<Link to="/manage/courtesycars/contracts/new">
|
||||||
<FileAddFilled />
|
<FileAddFilled />
|
||||||
{t("menus.header.courtesycars-newcontract")}
|
{t("menus.header.courtesycars-newcontract")}
|
||||||
</Link>
|
</Link>
|
||||||
@@ -191,43 +197,51 @@ function Header({
|
|||||||
<DollarCircleFilled />
|
<DollarCircleFilled />
|
||||||
<span>{t("menus.header.accounting")}</span>
|
<span>{t("menus.header.accounting")}</span>
|
||||||
</span>
|
</span>
|
||||||
}>
|
}
|
||||||
|
>
|
||||||
<Menu.Item
|
<Menu.Item
|
||||||
key='enterinvoices'
|
key="enterinvoices"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setInvoiceEnterContext({
|
setInvoiceEnterContext({
|
||||||
actions: {},
|
actions: {},
|
||||||
context: {},
|
context: {},
|
||||||
});
|
});
|
||||||
}}>
|
}}
|
||||||
|
>
|
||||||
{t("menus.header.enterinvoices")}
|
{t("menus.header.enterinvoices")}
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item key='invoices'>
|
<Menu.Item key="invoices">
|
||||||
<Link to='/manage/invoices'>{t("menus.header.invoices")}</Link>
|
<Link to="/manage/invoices">{t("menus.header.invoices")}</Link>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item
|
<Menu.Item
|
||||||
key='entertimetickets'
|
key="entertimetickets"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setTimeTicketContext({
|
setTimeTicketContext({
|
||||||
actions: {},
|
actions: {},
|
||||||
context: {},
|
context: {},
|
||||||
});
|
});
|
||||||
}}>
|
}}
|
||||||
|
>
|
||||||
{t("menus.header.entertimeticket")}
|
{t("menus.header.entertimeticket")}
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
|
<Menu.Item key="receivables">
|
||||||
|
<Link to="/manage/accounting/receivables">
|
||||||
|
{t("menus.header.accounting-receivables")}
|
||||||
|
</Link>
|
||||||
|
</Menu.Item>
|
||||||
</Menu.SubMenu>
|
</Menu.SubMenu>
|
||||||
|
|
||||||
<Menu.SubMenu title={t("menus.header.shop")}>
|
<Menu.SubMenu title={t("menus.header.shop")}>
|
||||||
<Menu.Item key='shop'>
|
<Menu.Item key="shop">
|
||||||
<Link to='/manage/shop'>{t("menus.header.shop_config")}</Link>
|
<Link to="/manage/shop">{t("menus.header.shop_config")}</Link>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item key='shop-templates'>
|
<Menu.Item key="shop-templates">
|
||||||
<Link to='/manage/shop/templates'>
|
<Link to="/manage/shop/templates">
|
||||||
{t("menus.header.shop_templates")}
|
{t("menus.header.shop_templates")}
|
||||||
</Link>
|
</Link>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item key='shop-vendors'>
|
<Menu.Item key="shop-vendors">
|
||||||
<Link to='/manage/shop/vendors'>
|
<Link to="/manage/shop/vendors">
|
||||||
{t("menus.header.shop_vendors")}
|
{t("menus.header.shop_vendors")}
|
||||||
</Link>
|
</Link>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
@@ -237,8 +251,8 @@ function Header({
|
|||||||
title={
|
title={
|
||||||
<div>
|
<div>
|
||||||
<Avatar
|
<Avatar
|
||||||
size='medium'
|
size="medium"
|
||||||
alt='Avatar'
|
alt="Avatar"
|
||||||
src={
|
src={
|
||||||
currentUser.photoURL ? currentUser.photoURL : UserImage
|
currentUser.photoURL ? currentUser.photoURL : UserImage
|
||||||
}
|
}
|
||||||
@@ -246,12 +260,13 @@ function Header({
|
|||||||
/>
|
/>
|
||||||
{currentUser.displayName || t("general.labels.unknown")}
|
{currentUser.displayName || t("general.labels.unknown")}
|
||||||
</div>
|
</div>
|
||||||
}>
|
}
|
||||||
|
>
|
||||||
<Menu.Item onClick={() => signOutStart()}>
|
<Menu.Item onClick={() => signOutStart()}>
|
||||||
{t("user.actions.signout")}
|
{t("user.actions.signout")}
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item>
|
<Menu.Item>
|
||||||
<Link to='/manage/profile'>
|
<Link to="/manage/profile">
|
||||||
{t("menus.currentuser.profile")}
|
{t("menus.currentuser.profile")}
|
||||||
</Link>
|
</Link>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
@@ -261,14 +276,15 @@ function Header({
|
|||||||
<GlobalOutlined />
|
<GlobalOutlined />
|
||||||
<span>{t("menus.currentuser.languageselector")}</span>
|
<span>{t("menus.currentuser.languageselector")}</span>
|
||||||
</span>
|
</span>
|
||||||
}>
|
}
|
||||||
<Menu.Item actiontype='lang-select' key='en-US'>
|
>
|
||||||
|
<Menu.Item actiontype="lang-select" key="en-US">
|
||||||
{t("general.languages.english")}
|
{t("general.languages.english")}
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item actiontype='lang-select' key='fr-CA'>
|
<Menu.Item actiontype="lang-select" key="fr-CA">
|
||||||
{t("general.languages.french")}
|
{t("general.languages.french")}
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item actiontype='lang-select' key='es-MX'>
|
<Menu.Item actiontype="lang-select" key="es-MX">
|
||||||
{t("general.languages.spanish")}
|
{t("general.languages.spanish")}
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
</Menu.SubMenu>
|
</Menu.SubMenu>
|
||||||
|
|||||||
@@ -1,43 +1,102 @@
|
|||||||
import { Button } from "antd";
|
import { useMutation } from "@apollo/react-hooks";
|
||||||
|
import { Button, notification } from "antd";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import React from "react";
|
import React, { useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { connect } from "react-redux";
|
||||||
|
import { createStructuredSelector } from "reselect";
|
||||||
import { auth } from "../../firebase/firebase.utils";
|
import { auth } from "../../firebase/firebase.utils";
|
||||||
|
import { UPDATE_JOB } from "../../graphql/jobs.queries";
|
||||||
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
|
const mapStateToProps = createStructuredSelector({
|
||||||
|
bodyshop: selectBodyshop,
|
||||||
|
});
|
||||||
|
|
||||||
export default function JobsCloseExportButton({ jobId, disabled }) {
|
export function JobsCloseExportButton({ bodyshop, jobId, disabled }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const [updateJob] = useMutation(UPDATE_JOB);
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
const handleQbxml = async () => {
|
const handleQbxml = async () => {
|
||||||
const response = await axios.post(
|
setLoading(true);
|
||||||
"/accounting/qbxml/receivables",
|
let QbXmlResponse;
|
||||||
{ jobId: jobId },
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${await auth.currentUser.getIdToken(true)}`,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
console.log("handle -> XML", response);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response2 = await axios.post(
|
QbXmlResponse = await axios.post(
|
||||||
"http://e9c5a8ed9079.ngrok.io/qb/receivables",
|
"/accounting/qbxml/receivables",
|
||||||
response.data,
|
{ jobId: jobId },
|
||||||
{
|
{
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${await auth.currentUser.getIdToken(true)}`,
|
Authorization: `Bearer ${await auth.currentUser.getIdToken(true)}`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
console.log("handle -> result", response2);
|
console.log("handle -> XML", QbXmlResponse);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("error", error, JSON.stringify(error));
|
console.log("Error getting QBXML from Server.", error);
|
||||||
|
notification["error"]({
|
||||||
|
message: t("jobs.errors.exporting", {
|
||||||
|
error: "Unable to retrieve QBXML. " + JSON.stringify(error.message),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
setLoading(false);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let PartnerResponse;
|
||||||
|
try {
|
||||||
|
PartnerResponse = await axios.post(
|
||||||
|
"http://e9c5a8ed9079.ngrok.io/qb/receivables",
|
||||||
|
QbXmlResponse.data,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${await auth.currentUser.getIdToken(true)}`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.log("Error connecting to quickbooks or partner.", error);
|
||||||
|
notification["error"]({
|
||||||
|
message: t("jobs.errors.exporting-partner"),
|
||||||
|
});
|
||||||
|
setLoading(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("PartnerResponse", PartnerResponse);
|
||||||
|
const jobUpdateResponse = await updateJob({
|
||||||
|
variables: {
|
||||||
|
jobId: jobId,
|
||||||
|
job: {
|
||||||
|
status: bodyshop.md_ro_statuses.default_exported || "Exported*",
|
||||||
|
date_exported: new Date(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!!!jobUpdateResponse.errors) {
|
||||||
|
notification["success"]({
|
||||||
|
message: t("jobs.successes.exported"),
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
notification["error"]({
|
||||||
|
message: t("jobs.errors.exporting", {
|
||||||
|
error: JSON.stringify(jobUpdateResponse.error),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
setLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Button onClick={handleQbxml} disabled={disabled} type="dashed">
|
<Button
|
||||||
|
onClick={handleQbxml}
|
||||||
|
loading={loading}
|
||||||
|
disabled={disabled}
|
||||||
|
type="dashed"
|
||||||
|
>
|
||||||
{t("jobs.actions.export")}
|
{t("jobs.actions.export")}
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, null)(JobsCloseExportButton);
|
||||||
|
|||||||
@@ -40,19 +40,6 @@ export function JobsCloseSaveButton({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
optimisticResponse: {
|
|
||||||
update_jobs: {
|
|
||||||
returning: {
|
|
||||||
id: jobId,
|
|
||||||
date_invoiced: new Date(),
|
|
||||||
status: bodyshop.md_ro_statuses.default_invoiced || "Invoiced*",
|
|
||||||
invoice_allocation: {
|
|
||||||
labMatAllocations,
|
|
||||||
partsAllocations,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
if (!!!result.errors) {
|
if (!!!result.errors) {
|
||||||
notification["success"]({ message: t("jobs.successes.invoiced") });
|
notification["success"]({ message: t("jobs.successes.invoiced") });
|
||||||
|
|||||||
29
client/src/graphql/accounting.queries.js
Normal file
29
client/src/graphql/accounting.queries.js
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import gql from "graphql-tag";
|
||||||
|
|
||||||
|
export const QUERY_JOBS_FOR_EXPORT = gql`
|
||||||
|
query QUERY_JOBS_FOR_EXPORT($invoicedStatus: String!) {
|
||||||
|
jobs(
|
||||||
|
where: {
|
||||||
|
date_exported: { _is_null: true }
|
||||||
|
status: { _eq: $invoicedStatus }
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
id
|
||||||
|
ro_number
|
||||||
|
ownr_fn
|
||||||
|
ownr_ln
|
||||||
|
ownr_co_nm
|
||||||
|
date_invoiced
|
||||||
|
date_exported
|
||||||
|
status
|
||||||
|
v_model_desc
|
||||||
|
v_make_desc
|
||||||
|
v_model_yr
|
||||||
|
v_color
|
||||||
|
est_number
|
||||||
|
clm_total
|
||||||
|
clm_no
|
||||||
|
ins_co_nm
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
@@ -366,8 +366,8 @@ export const UPDATE_JOB = gql`
|
|||||||
update_jobs(where: { id: { _eq: $jobId } }, _set: $job) {
|
update_jobs(where: { id: { _eq: $jobId } }, _set: $job) {
|
||||||
returning {
|
returning {
|
||||||
id
|
id
|
||||||
est_ph1
|
date_exported
|
||||||
est_ea
|
status
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -824,7 +824,7 @@ export const QUERY_JOB_CLOSE_DETAILS = gql`
|
|||||||
rate_mapa
|
rate_mapa
|
||||||
rate_mash
|
rate_mash
|
||||||
rate_matd
|
rate_matd
|
||||||
status
|
status
|
||||||
owner_owing
|
owner_owing
|
||||||
joblines {
|
joblines {
|
||||||
id
|
id
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
import { useQuery } from "@apollo/react-hooks";
|
||||||
|
import React, { useEffect } from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { connect } from "react-redux";
|
||||||
|
import { createStructuredSelector } from "reselect";
|
||||||
|
import AccountingReceivablesTable from "../../components/accounting-receivables-table/accounting-receivables-table.component";
|
||||||
|
import AlertComponent from "../../components/alert/alert.component";
|
||||||
|
import { QUERY_JOBS_FOR_EXPORT } from "../../graphql/accounting.queries";
|
||||||
|
import { setBreadcrumbs } from "../../redux/application/application.actions";
|
||||||
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
|
|
||||||
|
const mapStateToProps = createStructuredSelector({
|
||||||
|
bodyshop: selectBodyshop,
|
||||||
|
});
|
||||||
|
|
||||||
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
setBreadcrumbs: (breadcrumbs) => dispatch(setBreadcrumbs(breadcrumbs)),
|
||||||
|
});
|
||||||
|
export function AccountingReceivablesContainer({ bodyshop, setBreadcrumbs }) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
document.title = t("titles.accounting-receivables");
|
||||||
|
setBreadcrumbs([
|
||||||
|
{
|
||||||
|
link: "/manage/accounting/receivables",
|
||||||
|
label: t("titles.bc.accounting-receivables"),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}, [t, setBreadcrumbs]);
|
||||||
|
|
||||||
|
const { loading, error, data } = useQuery(QUERY_JOBS_FOR_EXPORT, {
|
||||||
|
variables: {
|
||||||
|
invoicedStatus: bodyshop.md_ro_statuses.default_invoiced || "Invoiced*",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (error) return <AlertComponent message={error.message} type="error" />;
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<AccountingReceivablesTable
|
||||||
|
loadaing={loading}
|
||||||
|
jobs={data ? data.jobs : []}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)(AccountingReceivablesContainer);
|
||||||
@@ -91,6 +91,9 @@ const ShopTemplates = lazy(() =>
|
|||||||
const JobIntake = lazy(() =>
|
const JobIntake = lazy(() =>
|
||||||
import("../jobs-intake/jobs-intake.page.container")
|
import("../jobs-intake/jobs-intake.page.container")
|
||||||
);
|
);
|
||||||
|
const AccountingReceivables = lazy(() =>
|
||||||
|
import("../accounting-receivables/accounting-receivables.container")
|
||||||
|
);
|
||||||
const AllJobs = lazy(() => import("../jobs-all/jobs-all.container"));
|
const AllJobs = lazy(() => import("../jobs-all/jobs-all.container"));
|
||||||
const JobsClose = lazy(() => import("../jobs-close/jobs-close.container"));
|
const JobsClose = lazy(() => import("../jobs-close/jobs-close.container"));
|
||||||
|
|
||||||
@@ -118,8 +121,9 @@ export function Manage({ match, conflict }) {
|
|||||||
</Header>
|
</Header>
|
||||||
<Layout>
|
<Layout>
|
||||||
<Content
|
<Content
|
||||||
className='content-container'
|
className="content-container"
|
||||||
style={{ padding: "0em 4em 4em" }}>
|
style={{ padding: "0em 4em 4em" }}
|
||||||
|
>
|
||||||
<FcmNotification />
|
<FcmNotification />
|
||||||
<ErrorBoundary>
|
<ErrorBoundary>
|
||||||
{conflict ? (
|
{conflict ? (
|
||||||
@@ -128,7 +132,8 @@ export function Manage({ match, conflict }) {
|
|||||||
<Suspense
|
<Suspense
|
||||||
fallback={
|
fallback={
|
||||||
<LoadingSpinner message={t("general.labels.loadingapp")} />
|
<LoadingSpinner message={t("general.labels.loadingapp")} />
|
||||||
}>
|
}
|
||||||
|
>
|
||||||
<BreadCrumbs />
|
<BreadCrumbs />
|
||||||
<EnterInvoiceModalContainer />
|
<EnterInvoiceModalContainer />
|
||||||
<EmailOverlayContainer />
|
<EmailOverlayContainer />
|
||||||
@@ -267,6 +272,11 @@ export function Manage({ match, conflict }) {
|
|||||||
path={`${match.path}/shop/vendors`}
|
path={`${match.path}/shop/vendors`}
|
||||||
component={ShopVendorPageContainer}
|
component={ShopVendorPageContainer}
|
||||||
/>
|
/>
|
||||||
|
<Route
|
||||||
|
exact
|
||||||
|
path={`${match.path}/accounting/receivables`}
|
||||||
|
component={AccountingReceivables}
|
||||||
|
/>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
)}
|
)}
|
||||||
</ErrorBoundary>
|
</ErrorBoundary>
|
||||||
|
|||||||
@@ -513,6 +513,8 @@
|
|||||||
"addingtoproduction": "Error adding to production. {{error}}",
|
"addingtoproduction": "Error adding to production. {{error}}",
|
||||||
"creating": "Error encountered while creating job. {{error}}",
|
"creating": "Error encountered while creating job. {{error}}",
|
||||||
"deleted": "Error deleting job.",
|
"deleted": "Error deleting job.",
|
||||||
|
"exporting": "Error exporting job. {{error}}",
|
||||||
|
"exporting-partner": "Unable to connect to ImEX Partner. Please ensure it is running and logged in.",
|
||||||
"invoicing": "Error invoicing job. {{error}}",
|
"invoicing": "Error invoicing job. {{error}}",
|
||||||
"noaccess": "This job does not exist or you do not have access to it.",
|
"noaccess": "This job does not exist or you do not have access to it.",
|
||||||
"nodamage": "No damage points on estimate.",
|
"nodamage": "No damage points on estimate.",
|
||||||
@@ -712,6 +714,7 @@
|
|||||||
"created_subtitle": "Estimate Number {{est_number}} has been created.",
|
"created_subtitle": "Estimate Number {{est_number}} has been created.",
|
||||||
"creatednoclick": "Job created successfully. ",
|
"creatednoclick": "Job created successfully. ",
|
||||||
"deleted": "Job deleted successfully.",
|
"deleted": "Job deleted successfully.",
|
||||||
|
"exported": "Job exported successfully. ",
|
||||||
"invoiced": "Job closed and invoiced successfully.",
|
"invoiced": "Job closed and invoiced successfully.",
|
||||||
"save": "Job saved successfully.",
|
"save": "Job saved successfully.",
|
||||||
"savetitle": "Record saved successfully.",
|
"savetitle": "Record saved successfully.",
|
||||||
@@ -726,6 +729,7 @@
|
|||||||
},
|
},
|
||||||
"header": {
|
"header": {
|
||||||
"accounting": "Accounting",
|
"accounting": "Accounting",
|
||||||
|
"accounting-receivables": "Receivables",
|
||||||
"activejobs": "Active Jobs",
|
"activejobs": "Active Jobs",
|
||||||
"alljobs": "All Jobs",
|
"alljobs": "All Jobs",
|
||||||
"availablejobs": "Available Jobs",
|
"availablejobs": "Available Jobs",
|
||||||
@@ -946,8 +950,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"titles": {
|
"titles": {
|
||||||
|
"accounting-receivables": "Receivables | $t(titles.app)",
|
||||||
"app": "ImEX Online",
|
"app": "ImEX Online",
|
||||||
"bc": {
|
"bc": {
|
||||||
|
"accounting-receivables": "Receivables",
|
||||||
"availablejobs": "Available Jobs",
|
"availablejobs": "Available Jobs",
|
||||||
"contracts": "Contracts",
|
"contracts": "Contracts",
|
||||||
"contracts-create": "New Contract",
|
"contracts-create": "New Contract",
|
||||||
|
|||||||
@@ -513,6 +513,8 @@
|
|||||||
"addingtoproduction": "",
|
"addingtoproduction": "",
|
||||||
"creating": "",
|
"creating": "",
|
||||||
"deleted": "Error al eliminar el trabajo.",
|
"deleted": "Error al eliminar el trabajo.",
|
||||||
|
"exporting": "",
|
||||||
|
"exporting-partner": "",
|
||||||
"invoicing": "",
|
"invoicing": "",
|
||||||
"noaccess": "Este trabajo no existe o no tiene acceso a él.",
|
"noaccess": "Este trabajo no existe o no tiene acceso a él.",
|
||||||
"nodamage": "",
|
"nodamage": "",
|
||||||
@@ -712,6 +714,7 @@
|
|||||||
"created_subtitle": "",
|
"created_subtitle": "",
|
||||||
"creatednoclick": "",
|
"creatednoclick": "",
|
||||||
"deleted": "Trabajo eliminado con éxito.",
|
"deleted": "Trabajo eliminado con éxito.",
|
||||||
|
"exported": "",
|
||||||
"invoiced": "",
|
"invoiced": "",
|
||||||
"save": "Trabajo guardado con éxito.",
|
"save": "Trabajo guardado con éxito.",
|
||||||
"savetitle": "Registro guardado con éxito.",
|
"savetitle": "Registro guardado con éxito.",
|
||||||
@@ -726,6 +729,7 @@
|
|||||||
},
|
},
|
||||||
"header": {
|
"header": {
|
||||||
"accounting": "",
|
"accounting": "",
|
||||||
|
"accounting-receivables": "",
|
||||||
"activejobs": "Empleos activos",
|
"activejobs": "Empleos activos",
|
||||||
"alljobs": "",
|
"alljobs": "",
|
||||||
"availablejobs": "Trabajos disponibles",
|
"availablejobs": "Trabajos disponibles",
|
||||||
@@ -946,8 +950,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"titles": {
|
"titles": {
|
||||||
|
"accounting-receivables": "",
|
||||||
"app": "ImEX Online",
|
"app": "ImEX Online",
|
||||||
"bc": {
|
"bc": {
|
||||||
|
"accounting-receivables": "",
|
||||||
"availablejobs": "",
|
"availablejobs": "",
|
||||||
"contracts": "",
|
"contracts": "",
|
||||||
"contracts-create": "",
|
"contracts-create": "",
|
||||||
|
|||||||
@@ -513,6 +513,8 @@
|
|||||||
"addingtoproduction": "",
|
"addingtoproduction": "",
|
||||||
"creating": "",
|
"creating": "",
|
||||||
"deleted": "Erreur lors de la suppression du travail.",
|
"deleted": "Erreur lors de la suppression du travail.",
|
||||||
|
"exporting": "",
|
||||||
|
"exporting-partner": "",
|
||||||
"invoicing": "",
|
"invoicing": "",
|
||||||
"noaccess": "Ce travail n'existe pas ou vous n'y avez pas accès.",
|
"noaccess": "Ce travail n'existe pas ou vous n'y avez pas accès.",
|
||||||
"nodamage": "",
|
"nodamage": "",
|
||||||
@@ -712,6 +714,7 @@
|
|||||||
"created_subtitle": "",
|
"created_subtitle": "",
|
||||||
"creatednoclick": "",
|
"creatednoclick": "",
|
||||||
"deleted": "Le travail a bien été supprimé.",
|
"deleted": "Le travail a bien été supprimé.",
|
||||||
|
"exported": "",
|
||||||
"invoiced": "",
|
"invoiced": "",
|
||||||
"save": "Le travail a été enregistré avec succès.",
|
"save": "Le travail a été enregistré avec succès.",
|
||||||
"savetitle": "Enregistrement enregistré avec succès.",
|
"savetitle": "Enregistrement enregistré avec succès.",
|
||||||
@@ -726,6 +729,7 @@
|
|||||||
},
|
},
|
||||||
"header": {
|
"header": {
|
||||||
"accounting": "",
|
"accounting": "",
|
||||||
|
"accounting-receivables": "",
|
||||||
"activejobs": "Emplois actifs",
|
"activejobs": "Emplois actifs",
|
||||||
"alljobs": "",
|
"alljobs": "",
|
||||||
"availablejobs": "Emplois disponibles",
|
"availablejobs": "Emplois disponibles",
|
||||||
@@ -946,8 +950,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"titles": {
|
"titles": {
|
||||||
|
"accounting-receivables": "",
|
||||||
"app": "ImEX Online",
|
"app": "ImEX Online",
|
||||||
"bc": {
|
"bc": {
|
||||||
|
"accounting-receivables": "",
|
||||||
"availablejobs": "",
|
"availablejobs": "",
|
||||||
"contracts": "",
|
"contracts": "",
|
||||||
"contracts-create": "",
|
"contracts-create": "",
|
||||||
|
|||||||
Reference in New Issue
Block a user