Artifact 5f4f817e7eee3794b96ab7792e7e9d0f56e0fc0392fdec0291a67201e6fcd9c8:
- File
shared/ql361api/src/ql361api/purchases.gleam
— part of check-in
[74ded990b8]
at
2026-10-23 05:24:52
on branch trunk
— 总仓的采购入库单改为只读同步,并在本地生成批次码。
轮询和人工同步都只拉取已记账的总仓采购入库单,红冲和只作显示的仓库不入库。批次码写在本地,不回来肯。 (user: pluto size: 9242)
import gleam/dynamic/decode import gleam/json import gleam/option.{type Option, None, Some} import gleam/result import ql361api/client.{type Client} import ql361api/json_codec import ql361api/models.{ type ApiError, type Page, type PurchaseOrder, type PurchaseOrderSummary, JsonError, Page, PurchaseOrder, PurchaseOrderItem, PurchaseOrderSummary, } import ql361api/orders /// 来肯采购订单。状态 20 是待收货,入库仓库字段是 sinid / sinfullname。 pub const purchase_order_billtype = 504 pub const purchase_receipt_billtype = 501 pub const pending_receipt_status = 20 pub const posted_receipt_status = 20 pub const page_size = 100 pub fn fetch_purchase_order_page( client client: Client, begin_date begin_date: String, end_date end_date: String, status status: Option(Int), page page: Int, page_size page_size: Int, ) -> Result(Page(PurchaseOrderSummary), ApiError) { fetch_bill_page( client, purchase_order_billtype, begin_date, end_date, status, page, page_size, ) } pub fn fetch_purchase_receipt_page( client client: Client, begin_date begin_date: String, end_date end_date: String, page page: Int, page_size page_size: Int, ) -> Result(Page(PurchaseOrderSummary), ApiError) { fetch_bill_page( client, purchase_receipt_billtype, begin_date, end_date, Some(posted_receipt_status), page, page_size, ) } fn fetch_bill_page( client: Client, billtype: Int, begin_date: String, end_date: String, status: Option(Int), page: Int, page_size: Int, ) -> Result(Page(PurchaseOrderSummary), ApiError) { let condition = [ #("begindate", json.string(begin_date)), #("enddate", json.string(end_date)), #("billtype", json.int(billtype)), ] let condition = case status { Some(value) -> [#("status", json.int(value)), ..condition] None -> condition } let payload = json.object([ #( "reportparam", json.object([ #("orders", json.string("")), #("parid", json.int(0)), #("pagetype", json.string("erp")), #("displaytype", json.string("tree")), #("pagerow", json.int(page_size)), #("pagenumber", json.int(page)), ]), ), #("conditionparam", json.object(condition)), ]) |> json.to_string use raw_json <- result.try( client.post_rpc(client, orders.query_orders_method, "erp", payload), ) parse_purchase_orders_body(raw_json) } pub fn fetch_purchase_order_detail( client client: Client, bill_id bill_id: Int, ) -> Result(PurchaseOrder, ApiError) { fetch_bill_detail(client, purchase_order_billtype, bill_id) } pub fn fetch_purchase_receipt_detail( client client: Client, bill_id bill_id: Int, ) -> Result(PurchaseOrder, ApiError) { fetch_bill_detail(client, purchase_receipt_billtype, bill_id) } fn fetch_bill_detail( client: Client, billtype: Int, bill_id: Int, ) -> Result(PurchaseOrder, ApiError) { let payload = json.object([ #("billid", json.int(bill_id)), #("billtype", json.int(billtype)), ]) |> json.to_string use raw_json <- result.try( client.post_rpc(client, orders.get_full_data_method, "erp", payload), ) parse_purchase_detail_body(raw_json) } pub fn parse_purchase_orders_body( body: String, ) -> Result(Page(PurchaseOrderSummary), ApiError) { let summary_decoder = { use bill_id <- decode.field("billid", json_codec.int()) use bill_code <- decode.optional_field("billcode", "", decode.string) use supplier_name <- decode.optional_field("dfullname", "", decode.string) use contact_person <- decode.optional_field("contactor", "", decode.string) use phone <- decode.optional_field("phone", "", decode.string) use warehouse_name <- decode.optional_field("sinfullname", "", decode.string) use warehouse_id <- decode.optional_field("sinid", 0, json_codec.int()) use bill_date <- decode.optional_field("billdate", "", decode.string) use order_status <- decode.optional_field("status", 0, json_codec.int()) use status_name <- decode.optional_field("statusname", "", decode.string) use total_qty <- decode.optional_field("qty", 0.0, json_codec.number()) use total_money <- decode.optional_field("totalmoney", 0.0, json_codec.number()) use remark <- decode.optional_field("remark", "", decode.string) use ifred <- decode.optional_field("ifred", 0, json_codec.int()) decode.success(PurchaseOrderSummary( bill_id: bill_id, bill_code: bill_code, supplier_name: supplier_name, contact_person: contact_person, phone: phone, warehouse_name: warehouse_name, warehouse_id: warehouse_id, bill_date: bill_date, status: order_status, status_name: status_name, total_qty: total_qty, total_money: total_money, remark: remark, ifred: ifred, )) } let data_decoder = { use items <- decode.field("datasource", decode.list(of: summary_decoder)) use total <- decode.optional_field("rowcount", 0, json_codec.int()) decode.success(Page(items: items, total: total)) } let wrapper_decoder = { use data <- decode.field("data", data_decoder) decode.success(data) } case json.parse(body, wrapper_decoder) { Ok(page) -> Ok(page) Error(_) -> Error(JsonError("采购订单列表响应无法解析")) } } pub fn parse_purchase_detail_body(body: String) -> Result(PurchaseOrder, ApiError) { let item_decoder = { use bill_detail_id <- decode.optional_field("billdetailid", 0, json_codec.int()) use sku_id <- decode.optional_field("skuid", 0, json_codec.int()) use goods_code <- decode.optional_field("gcode", "", decode.string) use goods_name <- decode.optional_field("gfullname", "", decode.string) use barcode <- decode.optional_field("barcode", "", decode.string) use spec <- decode.optional_field("spec", "", decode.string) use package_qty <- decode.optional_field("mqty", 0.0, json_codec.number()) use package_unit <- decode.optional_field("mufullname", "", decode.string) use base_qty <- decode.optional_field("qty", 0.0, json_codec.number()) use base_unit <- decode.optional_field("bufullname", "", decode.string) use price <- decode.optional_field("price", 0.0, json_codec.number()) use total_money <- decode.optional_field("totalmoney", 0.0, json_codec.number()) use position_code <- decode.optional_field("gpcode", "", decode.string) use area_code <- decode.optional_field("sacode", "", decode.string) decode.success(PurchaseOrderItem( bill_detail_id: bill_detail_id, sku_id: sku_id, goods_code: goods_code, goods_name: goods_name, barcode: barcode, spec: spec, package_qty: package_qty, package_unit: package_unit, base_qty: base_qty, base_unit: base_unit, price: price, total_money: total_money, position_code: position_code, area_code: area_code, )) } let body0_decoder = { use datasource <- decode.field("datasource", decode.list(of: item_decoder)) decode.success(datasource) } let header_decoder = { use bill_id <- decode.field("billid", json_codec.int()) use bill_code <- decode.optional_field("billcode", "", decode.string) use supplier_name <- decode.optional_field("dfullname", "", decode.string) use contact_person <- decode.optional_field("contactor", "", decode.string) use phone <- decode.optional_field("phone", "", decode.string) use warehouse_name <- decode.optional_field("sinfullname", "", decode.string) use warehouse_id <- decode.optional_field("sinid", 0, json_codec.int()) use bill_date <- decode.optional_field("billdate", "", decode.string) use order_status <- decode.optional_field("status", 0, json_codec.int()) use status_name <- decode.optional_field("statusname", "", decode.string) use total_qty <- decode.optional_field("qty", 0.0, json_codec.number()) use total_money <- decode.optional_field("totalmoney", 0.0, json_codec.number()) use remark <- decode.optional_field("remark", "", decode.string) decode.success(#( bill_id, bill_code, supplier_name, contact_person, phone, warehouse_name, warehouse_id, bill_date, order_status, status_name, total_qty, total_money, remark, )) } let data_decoder = { use header <- decode.field("header", header_decoder) use body0 <- decode.field("body0", body0_decoder) decode.success(PurchaseOrder( bill_id: header.0, bill_code: header.1, supplier_name: header.2, contact_person: header.3, phone: header.4, warehouse_name: header.5, warehouse_id: header.6, bill_date: header.7, status: header.8, status_name: header.9, total_qty: header.10, total_money: header.11, remark: header.12, items: body0, )) } let wrapper_decoder = { use data <- decode.field("data", data_decoder) decode.success(data) } case json.parse(body, wrapper_decoder) { Ok(order) -> Ok(order) Error(_) -> Error(JsonError("采购订单明细响应无法解析")) } }