fix
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
use che_tauri::{Filter, FilterSet};
|
||||
|
||||
use super::models::{Contract, Counterparty};
|
||||
|
||||
static CONTRACTAPP_FILTERS: &[Filter] = &[
|
||||
Filter::exact("id"),
|
||||
Filter::exact("name"),
|
||||
Filter::contains("name"),
|
||||
Filter::exact("number"),
|
||||
Filter::contains("number"),
|
||||
Filter::exact("date"),
|
||||
Filter::exact("status"),
|
||||
Filter::exact("status_name"),
|
||||
Filter::contains("status_name"),
|
||||
Filter::exact("contract_type"),
|
||||
Filter::contains("contract_type"),
|
||||
Filter::exact("category"),
|
||||
Filter::contains("category"),
|
||||
Filter::contains("counterparty_name"),
|
||||
Filter::contains("name_of_product"),
|
||||
Filter::exact("counterparty_id"),
|
||||
Filter::exact("project_id"),
|
||||
Filter::exact("frc_id"),
|
||||
Filter::exact("employee_id"),
|
||||
];
|
||||
|
||||
static COUNTERPARTY_FILTERS: &[Filter] = &[
|
||||
Filter::exact("id"),
|
||||
Filter::exact("name"),
|
||||
Filter::contains("name"),
|
||||
];
|
||||
|
||||
pub fn contractapp_filterset() -> FilterSet<Contract> {
|
||||
FilterSet::new(CONTRACTAPP_FILTERS)
|
||||
}
|
||||
|
||||
pub fn counterparty_filterset() -> FilterSet<Counterparty> {
|
||||
FilterSet::new(COUNTERPARTY_FILTERS)
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
CREATE TABLE IF NOT EXISTS contractapp (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL,
|
||||
number TEXT NOT NULL
|
||||
);
|
||||
@@ -0,0 +1,6 @@
|
||||
CREATE TABLE IF NOT EXISTS counterparty (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL
|
||||
);
|
||||
|
||||
ALTER TABLE contractapp ADD COLUMN counterparty_id INTEGER REFERENCES counterparty(id);
|
||||
@@ -0,0 +1,5 @@
|
||||
ALTER TABLE contractapp ADD COLUMN project_id INTEGER REFERENCES project(id);
|
||||
|
||||
ALTER TABLE contractapp ADD COLUMN frc_id INTEGER REFERENCES frc(id);
|
||||
|
||||
ALTER TABLE contractapp ADD COLUMN employee_id INTEGER REFERENCES employee(id);
|
||||
@@ -0,0 +1,43 @@
|
||||
ALTER TABLE contractapp ADD COLUMN absolute_url TEXT NOT NULL DEFAULT '';
|
||||
|
||||
ALTER TABLE contractapp ADD COLUMN contract_type TEXT NOT NULL DEFAULT '';
|
||||
|
||||
ALTER TABLE contractapp ADD COLUMN category TEXT NOT NULL DEFAULT '';
|
||||
|
||||
ALTER TABLE contractapp ADD COLUMN amount_total_display TEXT NOT NULL DEFAULT '';
|
||||
|
||||
ALTER TABLE contractapp ADD COLUMN amount_by_ds TEXT NOT NULL DEFAULT '';
|
||||
|
||||
ALTER TABLE contractapp ADD COLUMN comment TEXT NOT NULL DEFAULT '';
|
||||
|
||||
ALTER TABLE contractapp ADD COLUMN date TEXT NOT NULL DEFAULT '';
|
||||
|
||||
ALTER TABLE contractapp ADD COLUMN status_name TEXT NOT NULL DEFAULT '';
|
||||
|
||||
ALTER TABLE contractapp ADD COLUMN status TEXT NOT NULL DEFAULT '';
|
||||
|
||||
ALTER TABLE contractapp ADD COLUMN nds TEXT NOT NULL DEFAULT '';
|
||||
|
||||
ALTER TABLE contractapp ADD COLUMN name_of_product TEXT NOT NULL DEFAULT '';
|
||||
|
||||
ALTER TABLE contractapp ADD COLUMN counterparty_name TEXT NOT NULL DEFAULT '';
|
||||
|
||||
ALTER TABLE contractapp ADD COLUMN amount REAL NOT NULL DEFAULT 0;
|
||||
|
||||
ALTER TABLE contractapp ADD COLUMN month_pay REAL;
|
||||
|
||||
ALTER TABLE contractapp ADD COLUMN avans_pay TEXT NOT NULL DEFAULT '';
|
||||
|
||||
ALTER TABLE contractapp ADD COLUMN amount_total REAL NOT NULL DEFAULT 0;
|
||||
|
||||
ALTER TABLE contractapp ADD COLUMN estimate_nds_cost REAL NOT NULL DEFAULT 0;
|
||||
|
||||
ALTER TABLE contractapp ADD COLUMN estimate_nds_cert REAL NOT NULL DEFAULT 0;
|
||||
|
||||
ALTER TABLE contractapp ADD COLUMN bill_cost_sum REAL;
|
||||
|
||||
ALTER TABLE contractapp ADD COLUMN bill_paid_sum REAL;
|
||||
|
||||
ALTER TABLE contractapp ADD COLUMN income_total REAL NOT NULL DEFAULT 0;
|
||||
|
||||
ALTER TABLE contractapp ADD COLUMN arrears REAL NOT NULL DEFAULT 0;
|
||||
@@ -0,0 +1,367 @@
|
||||
{
|
||||
"models": [
|
||||
{
|
||||
"table": "contractapp",
|
||||
"fields": [
|
||||
{
|
||||
"name": "id",
|
||||
"ty": "integer",
|
||||
"primary_key": true,
|
||||
"nullable": false,
|
||||
"auto": true,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": null
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"ty": "text",
|
||||
"primary_key": false,
|
||||
"nullable": false,
|
||||
"auto": false,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": null
|
||||
},
|
||||
{
|
||||
"name": "number",
|
||||
"ty": "text",
|
||||
"primary_key": false,
|
||||
"nullable": false,
|
||||
"auto": false,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": null
|
||||
},
|
||||
{
|
||||
"name": "absolute_url",
|
||||
"ty": "text",
|
||||
"primary_key": false,
|
||||
"nullable": false,
|
||||
"auto": false,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": null
|
||||
},
|
||||
{
|
||||
"name": "contract_type",
|
||||
"ty": "text",
|
||||
"primary_key": false,
|
||||
"nullable": false,
|
||||
"auto": false,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": null
|
||||
},
|
||||
{
|
||||
"name": "category",
|
||||
"ty": "text",
|
||||
"primary_key": false,
|
||||
"nullable": false,
|
||||
"auto": false,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": null
|
||||
},
|
||||
{
|
||||
"name": "amount_total_display",
|
||||
"ty": "text",
|
||||
"primary_key": false,
|
||||
"nullable": false,
|
||||
"auto": false,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": null
|
||||
},
|
||||
{
|
||||
"name": "amount_by_ds",
|
||||
"ty": "text",
|
||||
"primary_key": false,
|
||||
"nullable": false,
|
||||
"auto": false,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": null
|
||||
},
|
||||
{
|
||||
"name": "comment",
|
||||
"ty": "text",
|
||||
"primary_key": false,
|
||||
"nullable": false,
|
||||
"auto": false,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": null
|
||||
},
|
||||
{
|
||||
"name": "date",
|
||||
"ty": "text",
|
||||
"primary_key": false,
|
||||
"nullable": false,
|
||||
"auto": false,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": null
|
||||
},
|
||||
{
|
||||
"name": "status_name",
|
||||
"ty": "text",
|
||||
"primary_key": false,
|
||||
"nullable": false,
|
||||
"auto": false,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": null
|
||||
},
|
||||
{
|
||||
"name": "status",
|
||||
"ty": "text",
|
||||
"primary_key": false,
|
||||
"nullable": false,
|
||||
"auto": false,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": null
|
||||
},
|
||||
{
|
||||
"name": "nds",
|
||||
"ty": "text",
|
||||
"primary_key": false,
|
||||
"nullable": false,
|
||||
"auto": false,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": null
|
||||
},
|
||||
{
|
||||
"name": "name_of_product",
|
||||
"ty": "text",
|
||||
"primary_key": false,
|
||||
"nullable": false,
|
||||
"auto": false,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": null
|
||||
},
|
||||
{
|
||||
"name": "counterparty_name",
|
||||
"ty": "text",
|
||||
"primary_key": false,
|
||||
"nullable": false,
|
||||
"auto": false,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": null
|
||||
},
|
||||
{
|
||||
"name": "amount",
|
||||
"ty": "real",
|
||||
"primary_key": false,
|
||||
"nullable": false,
|
||||
"auto": false,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": null
|
||||
},
|
||||
{
|
||||
"name": "month_pay",
|
||||
"ty": "real",
|
||||
"primary_key": false,
|
||||
"nullable": true,
|
||||
"auto": false,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": null
|
||||
},
|
||||
{
|
||||
"name": "avans_pay",
|
||||
"ty": "text",
|
||||
"primary_key": false,
|
||||
"nullable": false,
|
||||
"auto": false,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": null
|
||||
},
|
||||
{
|
||||
"name": "amount_total",
|
||||
"ty": "real",
|
||||
"primary_key": false,
|
||||
"nullable": false,
|
||||
"auto": false,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": null
|
||||
},
|
||||
{
|
||||
"name": "estimate_nds_cost",
|
||||
"ty": "real",
|
||||
"primary_key": false,
|
||||
"nullable": false,
|
||||
"auto": false,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": null
|
||||
},
|
||||
{
|
||||
"name": "estimate_nds_cert",
|
||||
"ty": "real",
|
||||
"primary_key": false,
|
||||
"nullable": false,
|
||||
"auto": false,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": null
|
||||
},
|
||||
{
|
||||
"name": "bill_cost_sum",
|
||||
"ty": "real",
|
||||
"primary_key": false,
|
||||
"nullable": true,
|
||||
"auto": false,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": null
|
||||
},
|
||||
{
|
||||
"name": "bill_paid_sum",
|
||||
"ty": "real",
|
||||
"primary_key": false,
|
||||
"nullable": true,
|
||||
"auto": false,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": null
|
||||
},
|
||||
{
|
||||
"name": "income_total",
|
||||
"ty": "real",
|
||||
"primary_key": false,
|
||||
"nullable": false,
|
||||
"auto": false,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": null
|
||||
},
|
||||
{
|
||||
"name": "arrears",
|
||||
"ty": "real",
|
||||
"primary_key": false,
|
||||
"nullable": false,
|
||||
"auto": false,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": null
|
||||
},
|
||||
{
|
||||
"name": "counterparty_id",
|
||||
"ty": "integer",
|
||||
"primary_key": false,
|
||||
"nullable": true,
|
||||
"auto": false,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": {
|
||||
"table": "counterparty",
|
||||
"column": "id"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "project_id",
|
||||
"ty": "integer",
|
||||
"primary_key": false,
|
||||
"nullable": true,
|
||||
"auto": false,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": {
|
||||
"table": "project",
|
||||
"column": "id"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "frc_id",
|
||||
"ty": "integer",
|
||||
"primary_key": false,
|
||||
"nullable": true,
|
||||
"auto": false,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": {
|
||||
"table": "frc",
|
||||
"column": "id"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "employee_id",
|
||||
"ty": "integer",
|
||||
"primary_key": false,
|
||||
"nullable": true,
|
||||
"auto": false,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": {
|
||||
"table": "employee",
|
||||
"column": "id"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"table": "counterparty",
|
||||
"fields": [
|
||||
{
|
||||
"name": "id",
|
||||
"ty": "integer",
|
||||
"primary_key": true,
|
||||
"nullable": false,
|
||||
"auto": true,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": null
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"ty": "text",
|
||||
"primary_key": false,
|
||||
"nullable": false,
|
||||
"auto": false,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": null
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
pub mod filters;
|
||||
pub mod models;
|
||||
pub mod serializers;
|
||||
|
||||
use che_tauri::{AppModule, ModuleContext};
|
||||
|
||||
pub fn module() -> ContractappModule {
|
||||
ContractappModule
|
||||
}
|
||||
|
||||
pub struct ContractappModule;
|
||||
|
||||
impl AppModule for ContractappModule {
|
||||
fn name(&self) -> &'static str {
|
||||
"contractapp"
|
||||
}
|
||||
|
||||
fn init(&self, ctx: &mut ModuleContext) {
|
||||
ctx.resource::<models::Contract>(
|
||||
"contract",
|
||||
serializers::contractapp_serializer(),
|
||||
filters::contractapp_filterset(),
|
||||
);
|
||||
ctx.resource::<models::Counterparty>(
|
||||
"counterparty",
|
||||
serializers::counterparty_serializer(),
|
||||
filters::counterparty_filterset(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
use che_orm::Model;
|
||||
|
||||
use crate::apps::{
|
||||
frcapp::models::Frc, personemanagment::models::Employee, projectapp::models::Project,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Model)]
|
||||
#[model(table = "contractapp")]
|
||||
pub struct Contract {
|
||||
#[field(primary_key)]
|
||||
pub id: i64,
|
||||
|
||||
pub name: String,
|
||||
pub number: String,
|
||||
pub absolute_url: String,
|
||||
pub contract_type: String,
|
||||
pub category: String,
|
||||
pub amount_total_display: String,
|
||||
pub amount_by_ds: String,
|
||||
pub comment: String,
|
||||
pub date: String,
|
||||
pub status_name: String,
|
||||
pub status: String,
|
||||
pub nds: String,
|
||||
pub name_of_product: String,
|
||||
pub counterparty_name: String,
|
||||
pub amount: f64,
|
||||
pub month_pay: Option<f64>,
|
||||
pub avans_pay: String,
|
||||
pub amount_total: f64,
|
||||
pub estimate_nds_cost: f64,
|
||||
pub estimate_nds_cert: f64,
|
||||
pub bill_cost_sum: Option<f64>,
|
||||
pub bill_paid_sum: Option<f64>,
|
||||
pub income_total: f64,
|
||||
pub arrears: f64,
|
||||
|
||||
#[field(foreign_key = Counterparty)]
|
||||
pub counterparty_id: Option<i64>,
|
||||
|
||||
#[field(foreign_key = Project)]
|
||||
pub project_id: Option<i64>,
|
||||
|
||||
#[field(foreign_key = Frc)]
|
||||
pub frc_id: Option<i64>,
|
||||
|
||||
#[field(foreign_key = Employee)]
|
||||
pub employee_id: Option<i64>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Model)]
|
||||
#[model(table = "counterparty")]
|
||||
pub struct Counterparty {
|
||||
#[field(primary_key)]
|
||||
pub id: i64,
|
||||
|
||||
pub name: String,
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
use che_tauri::{Field, ModelSerializer, RelatedModel};
|
||||
|
||||
use crate::apps::{
|
||||
frcapp::{models::Frc, serializers::frc_serializer},
|
||||
personemanagment::{models::Employee, serializers::employee_serializer},
|
||||
projectapp::{models::Project, serializers::project_serializer},
|
||||
};
|
||||
|
||||
use super::models::{Contract, Counterparty};
|
||||
|
||||
static CONTRACT_FIELDS: &[Field] = &[
|
||||
Field::new("id").read_only(),
|
||||
Field::new("name"),
|
||||
Field::new("number"),
|
||||
Field::new("absolute_url"),
|
||||
Field::new("contract_type"),
|
||||
Field::new("category"),
|
||||
Field::new("amount_total_display"),
|
||||
Field::new("amount_by_ds"),
|
||||
Field::new("comment"),
|
||||
Field::new("date"),
|
||||
Field::new("status_name"),
|
||||
Field::new("status"),
|
||||
Field::new("nds"),
|
||||
Field::new("name_of_product"),
|
||||
Field::new("counterparty_name"),
|
||||
Field::new("amount"),
|
||||
Field::new("month_pay").required(false).nullable(),
|
||||
Field::new("avans_pay"),
|
||||
Field::new("amount_total"),
|
||||
Field::new("estimate_nds_cost"),
|
||||
Field::new("estimate_nds_cert"),
|
||||
Field::new("bill_cost_sum").required(false).nullable(),
|
||||
Field::new("bill_paid_sum").required(false).nullable(),
|
||||
Field::new("income_total"),
|
||||
Field::new("arrears"),
|
||||
Field::new("counterparty_id").required(false).nullable(),
|
||||
Field::new("project_id").required(false).nullable(),
|
||||
Field::new("frc_id").required(false).nullable(),
|
||||
Field::new("employee_id").required(false).nullable(),
|
||||
Field::related("counterparty", "counterparty_id", &COUNTERPARTY_RELATION),
|
||||
Field::related("project", "project_id", &PROJECT_RELATION),
|
||||
Field::related("frc", "frc_id", &FRC_RELATION),
|
||||
Field::related("employee", "employee_id", &EMPLOYEE_RELATION),
|
||||
];
|
||||
|
||||
static COUNTERPARTY_FIELDS: &[Field] = &[Field::new("id").read_only(), Field::new("name")];
|
||||
static COUNTERPARTY_RELATION: RelatedModel<Counterparty> =
|
||||
RelatedModel::new(counterparty_serializer);
|
||||
static PROJECT_RELATION: RelatedModel<Project> = RelatedModel::new(project_serializer);
|
||||
static FRC_RELATION: RelatedModel<Frc> = RelatedModel::new(frc_serializer);
|
||||
static EMPLOYEE_RELATION: RelatedModel<Employee> = RelatedModel::new(employee_serializer);
|
||||
|
||||
pub fn contractapp_serializer() -> ModelSerializer<Contract> {
|
||||
ModelSerializer::new(CONTRACT_FIELDS)
|
||||
}
|
||||
|
||||
pub fn counterparty_serializer() -> ModelSerializer<Counterparty> {
|
||||
ModelSerializer::new(COUNTERPARTY_FIELDS)
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
use che_tauri::{Filter, FilterSet};
|
||||
|
||||
use super::models::Frc;
|
||||
|
||||
static FRC_FILTERS: &[Filter] = &[
|
||||
Filter::exact("id"),
|
||||
Filter::exact("name"),
|
||||
Filter::contains("name"),
|
||||
];
|
||||
|
||||
pub fn frc_filterset() -> FilterSet<Frc> {
|
||||
FilterSet::new(FRC_FILTERS)
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
CREATE TABLE IF NOT EXISTS frc (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL,
|
||||
icon TEXT NOT NULL,
|
||||
balance REAL NOT NULL
|
||||
);
|
||||
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"models": [
|
||||
{
|
||||
"table": "frc",
|
||||
"fields": [
|
||||
{
|
||||
"name": "id",
|
||||
"ty": "integer",
|
||||
"primary_key": true,
|
||||
"nullable": false,
|
||||
"auto": true,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": null
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"ty": "text",
|
||||
"primary_key": false,
|
||||
"nullable": false,
|
||||
"auto": false,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": null
|
||||
},
|
||||
{
|
||||
"name": "icon",
|
||||
"ty": "text",
|
||||
"primary_key": false,
|
||||
"nullable": false,
|
||||
"auto": false,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": null
|
||||
},
|
||||
{
|
||||
"name": "balance",
|
||||
"ty": "real",
|
||||
"primary_key": false,
|
||||
"nullable": false,
|
||||
"auto": false,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": null
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
pub mod filters;
|
||||
pub mod models;
|
||||
pub mod serializers;
|
||||
|
||||
use che_tauri::{AppModule, ModuleContext};
|
||||
|
||||
pub fn module() -> FrcModule {
|
||||
FrcModule
|
||||
}
|
||||
|
||||
pub struct FrcModule;
|
||||
|
||||
impl AppModule for FrcModule {
|
||||
fn name(&self) -> &'static str {
|
||||
"frcapp"
|
||||
}
|
||||
|
||||
fn init(&self, ctx: &mut ModuleContext) {
|
||||
ctx.resource::<models::Frc>(
|
||||
"frc",
|
||||
serializers::frc_serializer(),
|
||||
filters::frc_filterset(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
use che_orm::Model;
|
||||
|
||||
#[derive(Debug, Clone, Model)]
|
||||
#[model(table = "frc")]
|
||||
pub struct Frc {
|
||||
#[field(primary_key)]
|
||||
pub id: i64,
|
||||
|
||||
pub name: String,
|
||||
pub icon: String,
|
||||
pub balance: f64,
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
use che_tauri::{Field, ModelSerializer};
|
||||
|
||||
use super::models::Frc;
|
||||
|
||||
static FRC_FIELDS: &[Field] = &[
|
||||
Field::new("id").read_only(),
|
||||
Field::new("name"),
|
||||
Field::new("icon"),
|
||||
Field::new("balance"),
|
||||
];
|
||||
|
||||
pub fn frc_serializer() -> ModelSerializer<Frc> {
|
||||
ModelSerializer::new(FRC_FIELDS)
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
pub mod frcapp;
|
||||
pub mod personemanagment;
|
||||
pub mod projectapp;
|
||||
pub mod users;
|
||||
|
||||
use che_tauri::InstalledApps;
|
||||
@@ -6,5 +8,9 @@ use che_tauri::InstalledApps;
|
||||
pub fn installed_apps() -> InstalledApps {
|
||||
InstalledApps::new()
|
||||
.add(users::module())
|
||||
.add(frcapp::module())
|
||||
.add(projectapp::module())
|
||||
.add(personemanagment::module())
|
||||
.add(contractapp::module())
|
||||
}
|
||||
pub mod contractapp;
|
||||
|
||||
@@ -6,6 +6,8 @@ static EMPLOYEE_FILTERS: &[Filter] = &[
|
||||
Filter::exact("id"),
|
||||
Filter::exact("name"),
|
||||
Filter::contains("name"),
|
||||
Filter::exact("short_name"),
|
||||
Filter::contains("short_name"),
|
||||
];
|
||||
|
||||
static TASK_FILTERS: &[Filter] = &[
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
ALTER TABLE employee ADD COLUMN short_name TEXT NOT NULL DEFAULT '';
|
||||
|
||||
ALTER TABLE employee ADD COLUMN avatar_small TEXT;
|
||||
|
||||
ALTER TABLE employee DROP COLUMN avatar;
|
||||
@@ -26,7 +26,7 @@
|
||||
"foreign_key": null
|
||||
},
|
||||
{
|
||||
"name": "avatar",
|
||||
"name": "short_name",
|
||||
"ty": "text",
|
||||
"primary_key": false,
|
||||
"nullable": false,
|
||||
@@ -35,6 +35,17 @@
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": null
|
||||
},
|
||||
{
|
||||
"name": "avatar_small",
|
||||
"ty": "text",
|
||||
"primary_key": false,
|
||||
"nullable": true,
|
||||
"auto": false,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": null
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -8,7 +8,9 @@ pub struct Employee {
|
||||
|
||||
pub name: String,
|
||||
|
||||
pub avatar: String,
|
||||
pub short_name: String,
|
||||
|
||||
pub avatar_small: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Model)]
|
||||
|
||||
@@ -5,7 +5,8 @@ use super::models::{Employee, Message, Task};
|
||||
static EMPLOYEE_FIELDS: &[Field] = &[
|
||||
Field::new("id").read_only(),
|
||||
Field::new("name"),
|
||||
Field::new("avatar"),
|
||||
Field::new("short_name"),
|
||||
Field::new("avatar_small").required(false).nullable(),
|
||||
];
|
||||
|
||||
static TASK_FIELDS: &[Field] = &[
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
use che_tauri::{Filter, FilterSet};
|
||||
|
||||
use super::models::Project;
|
||||
|
||||
static PROJECT_FILTERS: &[Filter] = &[
|
||||
Filter::exact("id"),
|
||||
Filter::exact("name"),
|
||||
Filter::contains("name"),
|
||||
Filter::exact("short_name"),
|
||||
Filter::contains("short_name"),
|
||||
];
|
||||
|
||||
pub fn project_filterset() -> FilterSet<Project> {
|
||||
FilterSet::new(PROJECT_FILTERS)
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
CREATE TABLE IF NOT EXISTS project (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL,
|
||||
full_name TEXT NOT NULL,
|
||||
short_name TEXT NOT NULL,
|
||||
locality_id INTEGER,
|
||||
locality_name TEXT
|
||||
);
|
||||
@@ -0,0 +1,75 @@
|
||||
{
|
||||
"models": [
|
||||
{
|
||||
"table": "project",
|
||||
"fields": [
|
||||
{
|
||||
"name": "id",
|
||||
"ty": "integer",
|
||||
"primary_key": true,
|
||||
"nullable": false,
|
||||
"auto": true,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": null
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"ty": "text",
|
||||
"primary_key": false,
|
||||
"nullable": false,
|
||||
"auto": false,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": null
|
||||
},
|
||||
{
|
||||
"name": "full_name",
|
||||
"ty": "text",
|
||||
"primary_key": false,
|
||||
"nullable": false,
|
||||
"auto": false,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": null
|
||||
},
|
||||
{
|
||||
"name": "short_name",
|
||||
"ty": "text",
|
||||
"primary_key": false,
|
||||
"nullable": false,
|
||||
"auto": false,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": null
|
||||
},
|
||||
{
|
||||
"name": "locality_id",
|
||||
"ty": "integer",
|
||||
"primary_key": false,
|
||||
"nullable": true,
|
||||
"auto": false,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": null
|
||||
},
|
||||
{
|
||||
"name": "locality_name",
|
||||
"ty": "text",
|
||||
"primary_key": false,
|
||||
"nullable": true,
|
||||
"auto": false,
|
||||
"unique": false,
|
||||
"max_length": null,
|
||||
"default": null,
|
||||
"foreign_key": null
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
pub mod filters;
|
||||
pub mod models;
|
||||
pub mod serializers;
|
||||
|
||||
use che_tauri::{AppModule, ModuleContext};
|
||||
|
||||
pub fn module() -> ProjectModule {
|
||||
ProjectModule
|
||||
}
|
||||
|
||||
pub struct ProjectModule;
|
||||
|
||||
impl AppModule for ProjectModule {
|
||||
fn name(&self) -> &'static str {
|
||||
"projectapp"
|
||||
}
|
||||
|
||||
fn init(&self, ctx: &mut ModuleContext) {
|
||||
ctx.resource::<models::Project>(
|
||||
"project",
|
||||
serializers::project_serializer(),
|
||||
filters::project_filterset(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
use che_orm::Model;
|
||||
|
||||
#[derive(Debug, Clone, Model)]
|
||||
#[model(table = "project")]
|
||||
pub struct Project {
|
||||
#[field(primary_key)]
|
||||
pub id: i64,
|
||||
|
||||
pub name: String,
|
||||
pub full_name: String,
|
||||
pub short_name: String,
|
||||
pub locality_id: Option<i64>,
|
||||
pub locality_name: Option<String>,
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
use che_tauri::{Field, ModelSerializer};
|
||||
|
||||
use super::models::Project;
|
||||
|
||||
static PROJECT_FIELDS: &[Field] = &[
|
||||
Field::new("id").read_only(),
|
||||
Field::new("name"),
|
||||
Field::new("full_name"),
|
||||
Field::new("short_name"),
|
||||
Field::new("locality_id").required(false).nullable(),
|
||||
Field::new("locality_name").required(false).nullable(),
|
||||
];
|
||||
|
||||
pub fn project_serializer() -> ModelSerializer<Project> {
|
||||
ModelSerializer::new(PROJECT_FIELDS)
|
||||
}
|
||||
+49
-2
@@ -1,6 +1,9 @@
|
||||
pub mod apps;
|
||||
pub mod sync;
|
||||
|
||||
use che_tauri::{ApiError, ApiRequest, AppState, TauriApi};
|
||||
use che_tauri::{ApiError, ApiRequest, AppState, AuthTokenResponse, TauriApi};
|
||||
|
||||
use crate::sync::SyncContractsResult;
|
||||
|
||||
#[tauri::command]
|
||||
fn greet(name: &str) -> String {
|
||||
@@ -15,8 +18,44 @@ async fn che_api(
|
||||
api.dispatch(request).await
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn auth_login(
|
||||
api: tauri::State<'_, TauriApi>,
|
||||
username: String,
|
||||
password: String,
|
||||
) -> Result<AuthTokenResponse, ApiError> {
|
||||
api.login(username, password).await
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn auth_set_token(api: tauri::State<'_, TauriApi>, token: String) {
|
||||
api.set_auth_token(token);
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn auth_logout(api: tauri::State<'_, TauriApi>) {
|
||||
api.logout();
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn auth_status(api: tauri::State<'_, TauriApi>) -> bool {
|
||||
api.is_authenticated()
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn sync_contracts(api: tauri::State<'_, TauriApi>) -> Result<SyncContractsResult, ApiError> {
|
||||
sync::sync_contracts(&api).await
|
||||
}
|
||||
|
||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||
pub fn run() {
|
||||
#[cfg(target_os = "linux")]
|
||||
if std::env::var_os("WAYLAND_DISPLAY").is_some()
|
||||
&& std::env::var_os("WEBKIT_DISABLE_DMABUF_RENDERER").is_none()
|
||||
{
|
||||
std::env::set_var("WEBKIT_DISABLE_DMABUF_RENDERER", "1");
|
||||
}
|
||||
|
||||
let api = tauri::async_runtime::block_on(async {
|
||||
let state = AppState::from_config_file("app.toml").await?;
|
||||
TauriApi::new(state)
|
||||
@@ -29,7 +68,15 @@ pub fn run() {
|
||||
tauri::Builder::default()
|
||||
.manage(api)
|
||||
.plugin(tauri_plugin_opener::init())
|
||||
.invoke_handler(tauri::generate_handler![greet, che_api])
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
greet,
|
||||
che_api,
|
||||
auth_login,
|
||||
auth_set_token,
|
||||
auth_logout,
|
||||
auth_status,
|
||||
sync_contracts
|
||||
])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,321 @@
|
||||
use che_orm::__private::sqlx;
|
||||
use che_tauri::{ApiError, TauriApi};
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(Debug, serde::Serialize)]
|
||||
pub struct SyncContractsResult {
|
||||
pub synced: usize,
|
||||
pub pages: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct ContractPage {
|
||||
links: PageLinks,
|
||||
results: Vec<RemoteContract>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct PageLinks {
|
||||
next: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct RemoteContract {
|
||||
id: i64,
|
||||
name: String,
|
||||
number: String,
|
||||
#[serde(rename = "get_absolute_url")]
|
||||
absolute_url: String,
|
||||
#[serde(rename = "get_type")]
|
||||
contract_type: String,
|
||||
#[serde(rename = "get_category")]
|
||||
category: String,
|
||||
#[serde(rename = "get_amount_total")]
|
||||
amount_total_display: String,
|
||||
#[serde(rename = "get_amount_by_ds")]
|
||||
amount_by_ds: String,
|
||||
comment: String,
|
||||
date: String,
|
||||
#[serde(rename = "get_status")]
|
||||
status_name: String,
|
||||
status: String,
|
||||
nds: String,
|
||||
name_of_product: String,
|
||||
counterparty: String,
|
||||
amount: f64,
|
||||
month_pay: Option<f64>,
|
||||
avans_pay: String,
|
||||
amount_total: f64,
|
||||
estimate_nds_cost: f64,
|
||||
estimate_nds_cert: f64,
|
||||
#[serde(rename = "get_bill_cost")]
|
||||
bill_cost: Option<RemoteBillCost>,
|
||||
income_total: f64,
|
||||
arrears: f64,
|
||||
company: Option<RemoteCompany>,
|
||||
project: Option<RemoteProject>,
|
||||
frc: Option<RemoteFrc>,
|
||||
get_employee: Option<RemoteEmployee>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct RemoteBillCost {
|
||||
#[serde(rename = "cost__sum")]
|
||||
cost_sum: Option<f64>,
|
||||
#[serde(rename = "paid__sum")]
|
||||
paid_sum: Option<f64>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct RemoteCompany {
|
||||
id: i64,
|
||||
name: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct RemoteProject {
|
||||
id: i64,
|
||||
name: String,
|
||||
full_name: String,
|
||||
#[serde(rename = "get_short_name")]
|
||||
short_name: String,
|
||||
locality: Option<RemoteLocality>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
enum RemoteLocality {
|
||||
Object { id: i64, name: String },
|
||||
Id(i64),
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct RemoteFrc {
|
||||
id: i64,
|
||||
name: String,
|
||||
icon: Option<String>,
|
||||
#[serde(rename = "get_balance")]
|
||||
balance: Option<f64>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct RemoteEmployee {
|
||||
id: i64,
|
||||
name: String,
|
||||
short_name: String,
|
||||
avatar_small: Option<String>,
|
||||
}
|
||||
|
||||
pub async fn sync_contracts(api: &TauriApi) -> Result<SyncContractsResult, ApiError> {
|
||||
let state = api.state();
|
||||
let token = state
|
||||
.auth_token()
|
||||
.ok_or_else(|| ApiError::new("not_authenticated", "authentication token is missing"))?;
|
||||
let remote = state
|
||||
.config
|
||||
.remote
|
||||
.as_ref()
|
||||
.ok_or_else(|| ApiError::bad_request("sync requires [remote].base_url config"))?;
|
||||
let client = reqwest::Client::new();
|
||||
let mut next_url = Some(format!(
|
||||
"{}/api/contract/?page_size=100",
|
||||
remote.base_url.trim_end_matches('/')
|
||||
));
|
||||
let mut synced = 0;
|
||||
let mut pages = 0;
|
||||
|
||||
while let Some(url) = next_url {
|
||||
let response = client
|
||||
.get(url)
|
||||
.header(reqwest::header::AUTHORIZATION, format!("Token {token}"))
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
if !response.status().is_success() {
|
||||
let status = response.status();
|
||||
let detail = response.text().await.unwrap_or_default();
|
||||
return Err(ApiError::new(
|
||||
"remote_error",
|
||||
format!("remote request failed with {status}: {detail}"),
|
||||
));
|
||||
}
|
||||
|
||||
let page = response.json::<ContractPage>().await?;
|
||||
pages += 1;
|
||||
|
||||
for contract in &page.results {
|
||||
upsert_contract_dependencies(api, contract).await?;
|
||||
upsert_contract(api, contract).await?;
|
||||
synced += 1;
|
||||
}
|
||||
|
||||
next_url = page.links.next;
|
||||
}
|
||||
|
||||
Ok(SyncContractsResult { synced, pages })
|
||||
}
|
||||
|
||||
async fn upsert_contract_dependencies(
|
||||
api: &TauriApi,
|
||||
contract: &RemoteContract,
|
||||
) -> Result<(), ApiError> {
|
||||
let pool = api.state().db().pool();
|
||||
|
||||
if let Some(company) = &contract.company {
|
||||
sqlx::query(
|
||||
"INSERT INTO counterparty (id, name) VALUES (?1, ?2)
|
||||
ON CONFLICT(id) DO UPDATE SET name = excluded.name",
|
||||
)
|
||||
.bind(company.id)
|
||||
.bind(&company.name)
|
||||
.execute(pool)
|
||||
.await
|
||||
.map_err(database_error)?;
|
||||
}
|
||||
|
||||
if let Some(project) = &contract.project {
|
||||
let (locality_id, locality_name) = match &project.locality {
|
||||
Some(RemoteLocality::Object { id, name }) => (Some(*id), Some(name.as_str())),
|
||||
Some(RemoteLocality::Id(id)) => (Some(*id), None),
|
||||
None => (None, None),
|
||||
};
|
||||
sqlx::query(
|
||||
"INSERT INTO project (id, name, full_name, short_name, locality_id, locality_name)
|
||||
VALUES (?1, ?2, ?3, ?4, ?5, ?6)
|
||||
ON CONFLICT(id) DO UPDATE SET
|
||||
name = excluded.name,
|
||||
full_name = excluded.full_name,
|
||||
short_name = excluded.short_name,
|
||||
locality_id = excluded.locality_id,
|
||||
locality_name = excluded.locality_name",
|
||||
)
|
||||
.bind(project.id)
|
||||
.bind(&project.name)
|
||||
.bind(&project.full_name)
|
||||
.bind(&project.short_name)
|
||||
.bind(locality_id)
|
||||
.bind(locality_name)
|
||||
.execute(pool)
|
||||
.await
|
||||
.map_err(database_error)?;
|
||||
}
|
||||
|
||||
if let Some(frc) = &contract.frc {
|
||||
sqlx::query(
|
||||
"INSERT INTO frc (id, name, icon, balance) VALUES (?1, ?2, ?3, ?4)
|
||||
ON CONFLICT(id) DO UPDATE SET
|
||||
name = excluded.name,
|
||||
icon = excluded.icon,
|
||||
balance = excluded.balance",
|
||||
)
|
||||
.bind(frc.id)
|
||||
.bind(&frc.name)
|
||||
.bind(frc.icon.as_deref().unwrap_or_default())
|
||||
.bind(frc.balance.unwrap_or_default())
|
||||
.execute(pool)
|
||||
.await
|
||||
.map_err(database_error)?;
|
||||
}
|
||||
|
||||
if let Some(employee) = &contract.get_employee {
|
||||
sqlx::query(
|
||||
"INSERT INTO employee (id, name, short_name, avatar_small) VALUES (?1, ?2, ?3, ?4)
|
||||
ON CONFLICT(id) DO UPDATE SET
|
||||
name = excluded.name,
|
||||
short_name = excluded.short_name,
|
||||
avatar_small = excluded.avatar_small",
|
||||
)
|
||||
.bind(employee.id)
|
||||
.bind(&employee.name)
|
||||
.bind(&employee.short_name)
|
||||
.bind(employee.avatar_small.as_deref())
|
||||
.execute(pool)
|
||||
.await
|
||||
.map_err(database_error)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn upsert_contract(api: &TauriApi, contract: &RemoteContract) -> Result<(), ApiError> {
|
||||
sqlx::query(
|
||||
"INSERT INTO contractapp (
|
||||
id, name, number, absolute_url, contract_type, category, amount_total_display,
|
||||
amount_by_ds, comment, date, status_name, status, nds, name_of_product,
|
||||
counterparty_name, amount, month_pay, avans_pay, amount_total, estimate_nds_cost,
|
||||
estimate_nds_cert, bill_cost_sum, bill_paid_sum, income_total, arrears,
|
||||
counterparty_id, project_id, frc_id, employee_id
|
||||
)
|
||||
VALUES (
|
||||
?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15,
|
||||
?16, ?17, ?18, ?19, ?20, ?21, ?22, ?23, ?24, ?25, ?26, ?27, ?28, ?29
|
||||
)
|
||||
ON CONFLICT(id) DO UPDATE SET
|
||||
name = excluded.name,
|
||||
number = excluded.number,
|
||||
absolute_url = excluded.absolute_url,
|
||||
contract_type = excluded.contract_type,
|
||||
category = excluded.category,
|
||||
amount_total_display = excluded.amount_total_display,
|
||||
amount_by_ds = excluded.amount_by_ds,
|
||||
comment = excluded.comment,
|
||||
date = excluded.date,
|
||||
status_name = excluded.status_name,
|
||||
status = excluded.status,
|
||||
nds = excluded.nds,
|
||||
name_of_product = excluded.name_of_product,
|
||||
counterparty_name = excluded.counterparty_name,
|
||||
amount = excluded.amount,
|
||||
month_pay = excluded.month_pay,
|
||||
avans_pay = excluded.avans_pay,
|
||||
amount_total = excluded.amount_total,
|
||||
estimate_nds_cost = excluded.estimate_nds_cost,
|
||||
estimate_nds_cert = excluded.estimate_nds_cert,
|
||||
bill_cost_sum = excluded.bill_cost_sum,
|
||||
bill_paid_sum = excluded.bill_paid_sum,
|
||||
income_total = excluded.income_total,
|
||||
arrears = excluded.arrears,
|
||||
counterparty_id = excluded.counterparty_id,
|
||||
project_id = excluded.project_id,
|
||||
frc_id = excluded.frc_id,
|
||||
employee_id = excluded.employee_id",
|
||||
)
|
||||
.bind(contract.id)
|
||||
.bind(&contract.name)
|
||||
.bind(&contract.number)
|
||||
.bind(&contract.absolute_url)
|
||||
.bind(&contract.contract_type)
|
||||
.bind(&contract.category)
|
||||
.bind(&contract.amount_total_display)
|
||||
.bind(&contract.amount_by_ds)
|
||||
.bind(&contract.comment)
|
||||
.bind(&contract.date)
|
||||
.bind(&contract.status_name)
|
||||
.bind(&contract.status)
|
||||
.bind(&contract.nds)
|
||||
.bind(&contract.name_of_product)
|
||||
.bind(&contract.counterparty)
|
||||
.bind(contract.amount)
|
||||
.bind(contract.month_pay)
|
||||
.bind(&contract.avans_pay)
|
||||
.bind(contract.amount_total)
|
||||
.bind(contract.estimate_nds_cost)
|
||||
.bind(contract.estimate_nds_cert)
|
||||
.bind(contract.bill_cost.as_ref().and_then(|bill_cost| bill_cost.cost_sum))
|
||||
.bind(contract.bill_cost.as_ref().and_then(|bill_cost| bill_cost.paid_sum))
|
||||
.bind(contract.income_total)
|
||||
.bind(contract.arrears)
|
||||
.bind(contract.company.as_ref().map(|company| company.id))
|
||||
.bind(contract.project.as_ref().map(|project| project.id))
|
||||
.bind(contract.frc.as_ref().map(|frc| frc.id))
|
||||
.bind(contract.get_employee.as_ref().map(|employee| employee.id))
|
||||
.execute(api.state().db().pool())
|
||||
.await
|
||||
.map_err(database_error)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn database_error(error: sqlx::Error) -> ApiError {
|
||||
ApiError::new("database_error", error.to_string())
|
||||
}
|
||||
Reference in New Issue
Block a user