diff --git a/.gitignore b/.gitignore index cf862d6..ee677a7 100644 --- a/.gitignore +++ b/.gitignore @@ -98,3 +98,4 @@ Temporary Items # Local runtime data and certificates data/ +deploy/bin/ diff --git a/deploy/Dockerfile.purchase b/deploy/Dockerfile.purchase new file mode 100644 index 0000000..0685300 --- /dev/null +++ b/deploy/Dockerfile.purchase @@ -0,0 +1,7 @@ +FROM alpine:3.19 +RUN apk add --no-cache ca-certificates tzdata +WORKDIR /app +COPY deploy/bin/purchase . +COPY deploy/etc/purchase.yaml etc/purchase.yaml +EXPOSE 9003 +CMD ["./purchase", "-f", "etc/purchase.yaml"] diff --git a/deploy/docker-compose.yaml b/deploy/docker-compose.yaml index 894cc70..3394045 100644 --- a/deploy/docker-compose.yaml +++ b/deploy/docker-compose.yaml @@ -1,6 +1,6 @@ services: mysql: - image: mysql:8.0 + image: mysql:8.4 container_name: muyu-mysql restart: always environment: @@ -107,6 +107,22 @@ services: environment: TZ: Asia/Shanghai + purchase-rpc: + build: + context: .. + dockerfile: deploy/Dockerfile.purchase + container_name: muyu-purchase-rpc + restart: always + depends_on: + mysql: + condition: service_healthy + redis: + condition: service_healthy + etcd: + condition: service_healthy + environment: + TZ: Asia/Shanghai + gateway: build: context: .. @@ -116,9 +132,14 @@ services: ports: - "8888:8888" depends_on: - - system-rpc - - inventory-rpc - - postgres + system-rpc: + condition: service_started + inventory-rpc: + condition: service_started + purchase-rpc: + condition: service_started + postgres: + condition: service_healthy environment: TZ: Asia/Shanghai diff --git a/deploy/etc/gateway.yaml b/deploy/etc/gateway.yaml index ae837a0..626135d 100644 --- a/deploy/etc/gateway.yaml +++ b/deploy/etc/gateway.yaml @@ -26,6 +26,14 @@ InventoryRpc: NonBlock: true Timeout: 60000 +PurchaseRpc: + Etcd: + Hosts: + - etcd:2379 + Key: purchase.rpc + NonBlock: true + Timeout: 60000 + Log: ServiceName: gateway-api Mode: console diff --git a/deploy/etc/purchase.yaml b/deploy/etc/purchase.yaml new file mode 100644 index 0000000..4f5e2d3 --- /dev/null +++ b/deploy/etc/purchase.yaml @@ -0,0 +1,17 @@ +Name: purchase.rpc +ListenOn: 0.0.0.0:9003 + +Etcd: + Hosts: + - etcd:2379 + Key: purchase.rpc + +DataSource: root:muyu2026@tcp(mysql:3306)/muyu_wms?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai + +Cache: + - Host: redis:6379 + +Log: + ServiceName: purchase-rpc + Mode: console + Level: info diff --git a/deploy/mysql/migrations/20260329_add_tenant_id_to_legacy.sql b/deploy/mysql/migrations/20260329_add_tenant_id_to_legacy.sql index 861c1b2..89c2476 100644 --- a/deploy/mysql/migrations/20260329_add_tenant_id_to_legacy.sql +++ b/deploy/mysql/migrations/20260329_add_tenant_id_to_legacy.sql @@ -79,15 +79,50 @@ SET @s = IF(@c=0, CONCAT('ALTER TABLE `',@t,'` ADD COLUMN `tenant_id` VARCHAR(32 PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt; -- Add indexes for tenant_id on all tables -CREATE INDEX IF NOT EXISTS idx_sys_user_tenant ON sys_user(tenant_id); -CREATE INDEX IF NOT EXISTS idx_sys_role_tenant ON sys_role(tenant_id); -CREATE INDEX IF NOT EXISTS idx_sys_user_role_tenant ON sys_user_role(tenant_id); -CREATE INDEX IF NOT EXISTS idx_sys_menu_tenant ON sys_menu(tenant_id); -CREATE INDEX IF NOT EXISTS idx_sys_role_menu_tenant ON sys_role_menu(tenant_id); -CREATE INDEX IF NOT EXISTS idx_sys_config_tenant ON sys_config(tenant_id); -CREATE INDEX IF NOT EXISTS idx_inv_product_tenant ON inv_product(tenant_id); -CREATE INDEX IF NOT EXISTS idx_inv_stock_check_tenant ON inv_stock_check(tenant_id); -CREATE INDEX IF NOT EXISTS idx_inv_stock_check_detail_tenant ON inv_stock_check_detail(tenant_id); -CREATE INDEX IF NOT EXISTS idx_inv_stock_adjust_tenant ON inv_stock_adjust(tenant_id); -CREATE INDEX IF NOT EXISTS idx_inv_stock_adjust_detail_tenant ON inv_stock_adjust_detail(tenant_id); -CREATE INDEX IF NOT EXISTS idx_inv_stock_import_log_tenant ON inv_stock_import_log(tenant_id); +SET @i = (SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA='muyu_wms' AND TABLE_NAME='sys_user' AND INDEX_NAME='idx_sys_user_tenant'); +SET @s = IF(@i=0, 'CREATE INDEX idx_sys_user_tenant ON sys_user(tenant_id)', 'SELECT 1'); +PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt; + +SET @i = (SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA='muyu_wms' AND TABLE_NAME='sys_role' AND INDEX_NAME='idx_sys_role_tenant'); +SET @s = IF(@i=0, 'CREATE INDEX idx_sys_role_tenant ON sys_role(tenant_id)', 'SELECT 1'); +PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt; + +SET @i = (SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA='muyu_wms' AND TABLE_NAME='sys_user_role' AND INDEX_NAME='idx_sys_user_role_tenant'); +SET @s = IF(@i=0, 'CREATE INDEX idx_sys_user_role_tenant ON sys_user_role(tenant_id)', 'SELECT 1'); +PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt; + +SET @i = (SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA='muyu_wms' AND TABLE_NAME='sys_menu' AND INDEX_NAME='idx_sys_menu_tenant'); +SET @s = IF(@i=0, 'CREATE INDEX idx_sys_menu_tenant ON sys_menu(tenant_id)', 'SELECT 1'); +PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt; + +SET @i = (SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA='muyu_wms' AND TABLE_NAME='sys_role_menu' AND INDEX_NAME='idx_sys_role_menu_tenant'); +SET @s = IF(@i=0, 'CREATE INDEX idx_sys_role_menu_tenant ON sys_role_menu(tenant_id)', 'SELECT 1'); +PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt; + +SET @i = (SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA='muyu_wms' AND TABLE_NAME='sys_config' AND INDEX_NAME='idx_sys_config_tenant'); +SET @s = IF(@i=0, 'CREATE INDEX idx_sys_config_tenant ON sys_config(tenant_id)', 'SELECT 1'); +PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt; + +SET @i = (SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA='muyu_wms' AND TABLE_NAME='inv_product' AND INDEX_NAME='idx_inv_product_tenant'); +SET @s = IF(@i=0, 'CREATE INDEX idx_inv_product_tenant ON inv_product(tenant_id)', 'SELECT 1'); +PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt; + +SET @i = (SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA='muyu_wms' AND TABLE_NAME='inv_stock_check' AND INDEX_NAME='idx_inv_stock_check_tenant'); +SET @s = IF(@i=0, 'CREATE INDEX idx_inv_stock_check_tenant ON inv_stock_check(tenant_id)', 'SELECT 1'); +PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt; + +SET @i = (SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA='muyu_wms' AND TABLE_NAME='inv_stock_check_detail' AND INDEX_NAME='idx_inv_stock_check_detail_tenant'); +SET @s = IF(@i=0, 'CREATE INDEX idx_inv_stock_check_detail_tenant ON inv_stock_check_detail(tenant_id)', 'SELECT 1'); +PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt; + +SET @i = (SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA='muyu_wms' AND TABLE_NAME='inv_stock_adjust' AND INDEX_NAME='idx_inv_stock_adjust_tenant'); +SET @s = IF(@i=0, 'CREATE INDEX idx_inv_stock_adjust_tenant ON inv_stock_adjust(tenant_id)', 'SELECT 1'); +PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt; + +SET @i = (SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA='muyu_wms' AND TABLE_NAME='inv_stock_adjust_detail' AND INDEX_NAME='idx_inv_stock_adjust_detail_tenant'); +SET @s = IF(@i=0, 'CREATE INDEX idx_inv_stock_adjust_detail_tenant ON inv_stock_adjust_detail(tenant_id)', 'SELECT 1'); +PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt; + +SET @i = (SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA='muyu_wms' AND TABLE_NAME='inv_stock_import_log' AND INDEX_NAME='idx_inv_stock_import_log_tenant'); +SET @s = IF(@i=0, 'CREATE INDEX idx_inv_stock_import_log_tenant ON inv_stock_import_log(tenant_id)', 'SELECT 1'); +PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt; diff --git a/deploy/mysql/migrations/20260523_phase2_purchase_management.sql b/deploy/mysql/migrations/20260523_phase2_purchase_management.sql new file mode 100644 index 0000000..459536b --- /dev/null +++ b/deploy/mysql/migrations/20260523_phase2_purchase_management.sql @@ -0,0 +1,199 @@ +-- Phase 2: Purchase Management System +-- New tables: pur_supplier, pur_purchase_order, pur_purchase_order_detail, +-- pur_purchase_receipt, pur_purchase_receipt_detail, +-- pur_purchase_payment, inv_inventory_log + +-- ==================== Supplier ==================== + +CREATE TABLE IF NOT EXISTS `pur_supplier` ( + `id` BIGINT NOT NULL AUTO_INCREMENT, + `supplier_id` VARCHAR(32) NOT NULL, + `tenant_id` VARCHAR(32) NOT NULL DEFAULT '', + `supplier_name` VARCHAR(100) NOT NULL, + `phone` VARCHAR(100) NOT NULL DEFAULT '', + `purchase_count` INT NOT NULL DEFAULT 0 COMMENT 'redundant: total confirmed orders', + `delivered_qty` DECIMAL(10,2) NOT NULL DEFAULT 0.00 COMMENT 'redundant: total received quantity', + `payable_amount` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT 'redundant: sum of confirmed order contract amounts', + `paid_amount` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT 'redundant: sum of all payments', + `status` TINYINT NOT NULL DEFAULT 1 COMMENT '1:enabled 0:disabled', + `remark` TEXT, + `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + UNIQUE KEY `uk_supplier_id` (`supplier_id`), + UNIQUE KEY `uk_tenant_name` (`tenant_id`, `supplier_name`), + KEY `idx_tenant_id` (`tenant_id`), + KEY `idx_status` (`status`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='供应商档案'; + +-- ==================== Purchase Order ==================== + +CREATE TABLE IF NOT EXISTS `pur_purchase_order` ( + `id` BIGINT NOT NULL AUTO_INCREMENT, + `order_id` VARCHAR(32) NOT NULL, + `tenant_id` VARCHAR(32) NOT NULL DEFAULT '', + `order_no` VARCHAR(50) NOT NULL COMMENT 'format: PO-YYYYMMDD-0001', + `supplier_id` VARCHAR(32) NOT NULL, + `order_date` DATE NOT NULL, + `contract_amount` DECIMAL(12,2) NOT NULL DEFAULT 0.00, + `received_qty` DECIMAL(10,2) NOT NULL DEFAULT 0.00 COMMENT 'updated on receipt confirm', + `paid_amount` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT 'updated on payment create', + `payment_status` TINYINT NOT NULL DEFAULT 0 COMMENT '0:unpaid 1:partial 2:paid', + `receipt_status` TINYINT NOT NULL DEFAULT 0 COMMENT '0:none 1:partial 2:complete', + `purchase_by` VARCHAR(50) NOT NULL DEFAULT '', + `creator` VARCHAR(50) NOT NULL DEFAULT '', + `operator` VARCHAR(50) NOT NULL DEFAULT '', + `status` TINYINT NOT NULL DEFAULT 0 COMMENT '0:draft 1:confirmed 2:cancelled', + `remark` TEXT, + `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + UNIQUE KEY `uk_order_id` (`order_id`), + UNIQUE KEY `uk_tenant_order_no` (`tenant_id`, `order_no`), + KEY `idx_tenant_id` (`tenant_id`), + KEY `idx_supplier_id` (`supplier_id`), + KEY `idx_status` (`status`), + KEY `idx_order_date` (`order_date`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='采购订单'; + +-- ==================== Purchase Order Detail ==================== + +CREATE TABLE IF NOT EXISTS `pur_purchase_order_detail` ( + `id` BIGINT NOT NULL AUTO_INCREMENT, + `detail_id` VARCHAR(32) NOT NULL, + `tenant_id` VARCHAR(32) NOT NULL DEFAULT '', + `order_id` VARCHAR(32) NOT NULL, + `product_id` VARCHAR(32) NOT NULL, + `product_name` VARCHAR(100) NOT NULL DEFAULT '' COMMENT 'snapshot', + `spec` VARCHAR(100) NOT NULL DEFAULT '' COMMENT 'snapshot', + `color` VARCHAR(50) NOT NULL DEFAULT '' COMMENT 'snapshot', + `quantity` DECIMAL(10,2) NOT NULL DEFAULT 0.00, + `unit_price` DECIMAL(10,2) NOT NULL DEFAULT 0.00, + `amount` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT 'quantity * unit_price', + `received_qty` DECIMAL(10,2) NOT NULL DEFAULT 0.00 COMMENT 'updated on receipt confirm', + `remark` TEXT, + PRIMARY KEY (`id`), + UNIQUE KEY `uk_detail_id` (`detail_id`), + KEY `idx_order_id` (`order_id`), + KEY `idx_product_id` (`product_id`), + KEY `idx_tenant_id` (`tenant_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='采购订单明细'; + +-- ==================== Purchase Receipt ==================== + +CREATE TABLE IF NOT EXISTS `pur_purchase_receipt` ( + `id` BIGINT NOT NULL AUTO_INCREMENT, + `receipt_id` VARCHAR(32) NOT NULL, + `tenant_id` VARCHAR(32) NOT NULL DEFAULT '', + `receipt_no` VARCHAR(50) NOT NULL COMMENT 'format: REC-YYYYMMDD-0001', + `order_id` VARCHAR(32) NOT NULL, + `receipt_date` DATE NOT NULL, + `received_by` VARCHAR(50) NOT NULL DEFAULT '', + `status` TINYINT NOT NULL DEFAULT 0 COMMENT '0:draft 1:confirmed', + `remark` TEXT, + `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + UNIQUE KEY `uk_receipt_id` (`receipt_id`), + UNIQUE KEY `uk_tenant_receipt_no` (`tenant_id`, `receipt_no`), + KEY `idx_tenant_id` (`tenant_id`), + KEY `idx_order_id` (`order_id`), + KEY `idx_status` (`status`), + KEY `idx_receipt_date` (`receipt_date`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='采购入库单'; + +-- ==================== Purchase Receipt Detail ==================== + +CREATE TABLE IF NOT EXISTS `pur_purchase_receipt_detail` ( + `id` BIGINT NOT NULL AUTO_INCREMENT, + `detail_id` VARCHAR(32) NOT NULL, + `receipt_id` VARCHAR(32) NOT NULL, + `order_detail_id` VARCHAR(32) NOT NULL, + `product_id` VARCHAR(32) NOT NULL, + `actual_qty` DECIMAL(10,2) NOT NULL DEFAULT 0.00, + `unit_cost` DECIMAL(10,2) NOT NULL DEFAULT 0.00 COMMENT 'cost price snapshot from order detail', + `remark` TEXT, + PRIMARY KEY (`id`), + UNIQUE KEY `uk_detail_id` (`detail_id`), + KEY `idx_receipt_id` (`receipt_id`), + KEY `idx_order_detail_id` (`order_detail_id`), + KEY `idx_product_id` (`product_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='采购入库单明细'; + +-- ==================== Purchase Payment ==================== + +CREATE TABLE IF NOT EXISTS `pur_purchase_payment` ( + `id` BIGINT NOT NULL AUTO_INCREMENT, + `payment_id` VARCHAR(32) NOT NULL, + `tenant_id` VARCHAR(32) NOT NULL DEFAULT '', + `order_id` VARCHAR(32) NOT NULL, + `supplier_id` VARCHAR(32) NOT NULL, + `payment_date` DATE NOT NULL, + `amount` DECIMAL(12,2) NOT NULL DEFAULT 0.00, + `payment_method` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '现金/银行转账/微信/支付宝', + `operator` VARCHAR(50) NOT NULL DEFAULT '', + `remark` TEXT, + `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + UNIQUE KEY `uk_payment_id` (`payment_id`), + KEY `idx_tenant_id` (`tenant_id`), + KEY `idx_order_id` (`order_id`), + KEY `idx_supplier_id` (`supplier_id`), + KEY `idx_payment_date` (`payment_date`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='采购付款记录'; + +-- ==================== Inventory Log ==================== + +CREATE TABLE IF NOT EXISTS `inv_inventory_log` ( + `id` BIGINT NOT NULL AUTO_INCREMENT, + `log_id` VARCHAR(32) NOT NULL, + `tenant_id` VARCHAR(32) NOT NULL DEFAULT '', + `product_id` VARCHAR(32) NOT NULL, + `change_qty` DECIMAL(10,2) NOT NULL DEFAULT 0.00 COMMENT 'positive=in, negative=out', + `balance_after` DECIMAL(10,2) NOT NULL DEFAULT 0.00 COMMENT 'snapshot of quantity after change', + `change_type` TINYINT NOT NULL DEFAULT 1 COMMENT '1:purchase_in 2:sales_out 3:adjust 4:check', + `ref_type` VARCHAR(20) NOT NULL DEFAULT '' COMMENT 'PURCHASE/SALES/ADJUST/CHECK', + `ref_id` VARCHAR(32) NOT NULL DEFAULT '' COMMENT 'receipt_id / adjust_id etc.', + `contact_id` VARCHAR(32) NOT NULL DEFAULT '' COMMENT 'supplier_id or customer_id for display', + `log_date` DATE NOT NULL, + `operator` VARCHAR(50) NOT NULL DEFAULT '', + `remark` TEXT, + `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + UNIQUE KEY `uk_log_id` (`log_id`), + KEY `idx_tenant_id` (`tenant_id`), + KEY `idx_product_id` (`product_id`), + KEY `idx_change_type` (`change_type`), + KEY `idx_ref_id` (`ref_id`), + KEY `idx_log_date` (`log_date`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='库存变动日志'; + +-- ==================== Menu Seed Data ==================== + +-- Purchase management menu group and sub-menus +INSERT IGNORE INTO `sys_menu` (`menu_id`, `parent_id`, `menu_name`, `menu_type`, `path`, `component`, `permission`, `icon`, `sort_order`, `visible`, `status`) VALUES +('m_400', '', '采购管理', 1, '/purchase', '', '', 'ShoppingCartOutlined', 400, 1, 1), +('m_401', 'm_400', '供应商管理', 2, '/purchase/suppliers', './Purchase/Suppliers', 'purchase:supplier:list', 'ContactsOutlined', 1, 1, 1), +('m_402', 'm_400', '采购订单', 2, '/purchase/orders', './Purchase/Orders', 'purchase:order:list', 'FileTextOutlined', 2, 1, 1), +('m_403', 'm_400', '入库记录', 2, '/purchase/receipts', './Purchase/Receipts', 'purchase:receipt:list', 'InboxOutlined', 3, 1, 1), +('m_404', 'm_400', '采购报表', 2, '/purchase/stats', './Purchase/Stats', 'purchase:stats:view', 'BarChartOutlined', 4, 1, 1), +('m_207', 'm_200', '库存变动记录', 2, '/inventory/logs', './Inventory/Logs', 'inventory:log:list', 'HistoryOutlined', 7, 1, 1); + +-- Casbin policies for purchase module (admin gets all) +INSERT IGNORE INTO `casbin_rule` (`ptype`, `v0`, `v1`, `v2`) VALUES +('p', 'admin', '/api/v1/purchase/*', '*'), +('p', 'admin', '/api/v1/inventory/logs', 'GET'), +('p', 'warehouse', '/api/v1/inventory/logs', 'GET'), +('p', 'warehouse', '/api/v1/purchase/orders', 'GET'), +('p', 'warehouse', '/api/v1/purchase/orders/*', 'GET'), +('p', 'warehouse', '/api/v1/purchase/receipts', '*'), +('p', 'warehouse', '/api/v1/purchase/receipts/*', '*'); + +-- Grant all new menus to admin role +INSERT IGNORE INTO `sys_role_menu` (`role_id`, `menu_id`) +SELECT 'r_001', `menu_id` FROM `sys_menu` WHERE `menu_id` IN ('m_400','m_401','m_402','m_403','m_404','m_207'); + +-- Grant warehouse role access to receipts and inventory log menu +INSERT IGNORE INTO `sys_role_menu` (`role_id`, `menu_id`) VALUES +('r_002', 'm_402'), +('r_002', 'm_403'), +('r_002', 'm_207'); diff --git a/gateway/etc/gateway-api.yaml b/gateway/etc/gateway-api.yaml index ac9decd..dda2fdd 100644 --- a/gateway/etc/gateway-api.yaml +++ b/gateway/etc/gateway-api.yaml @@ -24,6 +24,13 @@ InventoryRpc: Key: inventory.rpc NonBlock: true +PurchaseRpc: + Etcd: + Hosts: + - 127.0.0.1:2379 + Key: purchase.rpc + NonBlock: true + Log: ServiceName: gateway-api Mode: console diff --git a/gateway/internal/config/config.go b/gateway/internal/config/config.go index 9e05208..4588aa2 100644 --- a/gateway/internal/config/config.go +++ b/gateway/internal/config/config.go @@ -19,4 +19,5 @@ type Config struct { PostgresDataSource string SystemRpc zrpc.RpcClientConf InventoryRpc zrpc.RpcClientConf + PurchaseRpc zrpc.RpcClientConf } diff --git a/gateway/internal/handler/inventory/log/listinventoryloghandler.go b/gateway/internal/handler/inventory/log/listinventoryloghandler.go new file mode 100644 index 0000000..831d147 --- /dev/null +++ b/gateway/internal/handler/inventory/log/listinventoryloghandler.go @@ -0,0 +1,28 @@ +package log + +import ( + "net/http" + + "github.com/zeromicro/go-zero/rest/httpx" + inventorylog "muyu-apiserver/gateway/internal/logic/inventory/log" + "muyu-apiserver/gateway/internal/svc" + "muyu-apiserver/gateway/internal/types" +) + +func ListInventoryLogHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.ListInventoryLogReq + if err := httpx.Parse(r, &req); err != nil { + httpx.ErrorCtx(r.Context(), w, err) + return + } + + l := inventorylog.NewListInventoryLogLogic(r.Context(), svcCtx) + resp, err := l.ListInventoryLog(&req) + if err != nil { + httpx.ErrorCtx(r.Context(), w, err) + } else { + httpx.OkJsonCtx(r.Context(), w, resp) + } + } +} diff --git a/gateway/internal/handler/purchase/order/cancelpurchaseorderhandler.go b/gateway/internal/handler/purchase/order/cancelpurchaseorderhandler.go new file mode 100644 index 0000000..7bcff9c --- /dev/null +++ b/gateway/internal/handler/purchase/order/cancelpurchaseorderhandler.go @@ -0,0 +1,21 @@ +package order + +import ( + "net/http" + + "github.com/zeromicro/go-zero/rest/httpx" + "muyu-apiserver/gateway/internal/logic/purchase/order" + "muyu-apiserver/gateway/internal/svc" +) + +func CancelPurchaseOrderHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + l := order.NewCancelPurchaseOrderLogic(r.Context(), svcCtx) + err := l.CancelPurchaseOrder() + if err != nil { + httpx.ErrorCtx(r.Context(), w, err) + } else { + httpx.OkJsonCtx(r.Context(), w, nil) + } + } +} diff --git a/gateway/internal/handler/purchase/order/confirmpurchaseorderhandler.go b/gateway/internal/handler/purchase/order/confirmpurchaseorderhandler.go new file mode 100644 index 0000000..c4e8c72 --- /dev/null +++ b/gateway/internal/handler/purchase/order/confirmpurchaseorderhandler.go @@ -0,0 +1,21 @@ +package order + +import ( + "net/http" + + "github.com/zeromicro/go-zero/rest/httpx" + "muyu-apiserver/gateway/internal/logic/purchase/order" + "muyu-apiserver/gateway/internal/svc" +) + +func ConfirmPurchaseOrderHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + l := order.NewConfirmPurchaseOrderLogic(r.Context(), svcCtx) + err := l.ConfirmPurchaseOrder() + if err != nil { + httpx.ErrorCtx(r.Context(), w, err) + } else { + httpx.OkJsonCtx(r.Context(), w, nil) + } + } +} diff --git a/gateway/internal/handler/purchase/order/createpurchaseorderhandler.go b/gateway/internal/handler/purchase/order/createpurchaseorderhandler.go new file mode 100644 index 0000000..21c6a28 --- /dev/null +++ b/gateway/internal/handler/purchase/order/createpurchaseorderhandler.go @@ -0,0 +1,28 @@ +package order + +import ( + "net/http" + + "github.com/zeromicro/go-zero/rest/httpx" + "muyu-apiserver/gateway/internal/logic/purchase/order" + "muyu-apiserver/gateway/internal/svc" + "muyu-apiserver/gateway/internal/types" +) + +func CreatePurchaseOrderHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.CreatePurchaseOrderReq + if err := httpx.Parse(r, &req); err != nil { + httpx.ErrorCtx(r.Context(), w, err) + return + } + + l := order.NewCreatePurchaseOrderLogic(r.Context(), svcCtx) + resp, err := l.CreatePurchaseOrder(&req) + if err != nil { + httpx.ErrorCtx(r.Context(), w, err) + } else { + httpx.OkJsonCtx(r.Context(), w, resp) + } + } +} diff --git a/gateway/internal/handler/purchase/order/getpurchaseorderhandler.go b/gateway/internal/handler/purchase/order/getpurchaseorderhandler.go new file mode 100644 index 0000000..1a5a35e --- /dev/null +++ b/gateway/internal/handler/purchase/order/getpurchaseorderhandler.go @@ -0,0 +1,21 @@ +package order + +import ( + "net/http" + + "github.com/zeromicro/go-zero/rest/httpx" + "muyu-apiserver/gateway/internal/logic/purchase/order" + "muyu-apiserver/gateway/internal/svc" +) + +func GetPurchaseOrderHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + l := order.NewGetPurchaseOrderLogic(r.Context(), svcCtx) + resp, err := l.GetPurchaseOrder() + if err != nil { + httpx.ErrorCtx(r.Context(), w, err) + } else { + httpx.OkJsonCtx(r.Context(), w, resp) + } + } +} diff --git a/gateway/internal/handler/purchase/order/listpurchaseorderhandler.go b/gateway/internal/handler/purchase/order/listpurchaseorderhandler.go new file mode 100644 index 0000000..4c027cf --- /dev/null +++ b/gateway/internal/handler/purchase/order/listpurchaseorderhandler.go @@ -0,0 +1,28 @@ +package order + +import ( + "net/http" + + "github.com/zeromicro/go-zero/rest/httpx" + "muyu-apiserver/gateway/internal/logic/purchase/order" + "muyu-apiserver/gateway/internal/svc" + "muyu-apiserver/gateway/internal/types" +) + +func ListPurchaseOrderHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.ListPurchaseOrderReq + if err := httpx.Parse(r, &req); err != nil { + httpx.ErrorCtx(r.Context(), w, err) + return + } + + l := order.NewListPurchaseOrderLogic(r.Context(), svcCtx) + resp, err := l.ListPurchaseOrder(&req) + if err != nil { + httpx.ErrorCtx(r.Context(), w, err) + } else { + httpx.OkJsonCtx(r.Context(), w, resp) + } + } +} diff --git a/gateway/internal/handler/purchase/order/updatepurchaseorderhandler.go b/gateway/internal/handler/purchase/order/updatepurchaseorderhandler.go new file mode 100644 index 0000000..00a6b6c --- /dev/null +++ b/gateway/internal/handler/purchase/order/updatepurchaseorderhandler.go @@ -0,0 +1,28 @@ +package order + +import ( + "net/http" + + "github.com/zeromicro/go-zero/rest/httpx" + "muyu-apiserver/gateway/internal/logic/purchase/order" + "muyu-apiserver/gateway/internal/svc" + "muyu-apiserver/gateway/internal/types" +) + +func UpdatePurchaseOrderHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.UpdatePurchaseOrderReq + if err := httpx.Parse(r, &req); err != nil { + httpx.ErrorCtx(r.Context(), w, err) + return + } + + l := order.NewUpdatePurchaseOrderLogic(r.Context(), svcCtx) + err := l.UpdatePurchaseOrder(&req) + if err != nil { + httpx.ErrorCtx(r.Context(), w, err) + } else { + httpx.OkJsonCtx(r.Context(), w, nil) + } + } +} diff --git a/gateway/internal/handler/purchase/payment/createpurchasepaymenthandler.go b/gateway/internal/handler/purchase/payment/createpurchasepaymenthandler.go new file mode 100644 index 0000000..9740b10 --- /dev/null +++ b/gateway/internal/handler/purchase/payment/createpurchasepaymenthandler.go @@ -0,0 +1,28 @@ +package payment + +import ( + "net/http" + + "github.com/zeromicro/go-zero/rest/httpx" + "muyu-apiserver/gateway/internal/logic/purchase/payment" + "muyu-apiserver/gateway/internal/svc" + "muyu-apiserver/gateway/internal/types" +) + +func CreatePurchasePaymentHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.CreatePurchasePaymentReq + if err := httpx.Parse(r, &req); err != nil { + httpx.ErrorCtx(r.Context(), w, err) + return + } + + l := payment.NewCreatePurchasePaymentLogic(r.Context(), svcCtx) + resp, err := l.CreatePurchasePayment(&req) + if err != nil { + httpx.ErrorCtx(r.Context(), w, err) + } else { + httpx.OkJsonCtx(r.Context(), w, resp) + } + } +} diff --git a/gateway/internal/handler/purchase/payment/listpurchasepaymenthandler.go b/gateway/internal/handler/purchase/payment/listpurchasepaymenthandler.go new file mode 100644 index 0000000..d3a35d3 --- /dev/null +++ b/gateway/internal/handler/purchase/payment/listpurchasepaymenthandler.go @@ -0,0 +1,28 @@ +package payment + +import ( + "net/http" + + "github.com/zeromicro/go-zero/rest/httpx" + "muyu-apiserver/gateway/internal/logic/purchase/payment" + "muyu-apiserver/gateway/internal/svc" + "muyu-apiserver/gateway/internal/types" +) + +func ListPurchasePaymentHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.ListPurchasePaymentReq + if err := httpx.Parse(r, &req); err != nil { + httpx.ErrorCtx(r.Context(), w, err) + return + } + + l := payment.NewListPurchasePaymentLogic(r.Context(), svcCtx) + resp, err := l.ListPurchasePayment(&req) + if err != nil { + httpx.ErrorCtx(r.Context(), w, err) + } else { + httpx.OkJsonCtx(r.Context(), w, resp) + } + } +} diff --git a/gateway/internal/handler/purchase/receipt/confirmpurchasereceipthandler.go b/gateway/internal/handler/purchase/receipt/confirmpurchasereceipthandler.go new file mode 100644 index 0000000..a998f0b --- /dev/null +++ b/gateway/internal/handler/purchase/receipt/confirmpurchasereceipthandler.go @@ -0,0 +1,21 @@ +package receipt + +import ( + "net/http" + + "github.com/zeromicro/go-zero/rest/httpx" + "muyu-apiserver/gateway/internal/logic/purchase/receipt" + "muyu-apiserver/gateway/internal/svc" +) + +func ConfirmPurchaseReceiptHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + l := receipt.NewConfirmPurchaseReceiptLogic(r.Context(), svcCtx) + err := l.ConfirmPurchaseReceipt() + if err != nil { + httpx.ErrorCtx(r.Context(), w, err) + } else { + httpx.OkJsonCtx(r.Context(), w, nil) + } + } +} diff --git a/gateway/internal/handler/purchase/receipt/createpurchasereceipthandler.go b/gateway/internal/handler/purchase/receipt/createpurchasereceipthandler.go new file mode 100644 index 0000000..e7e534a --- /dev/null +++ b/gateway/internal/handler/purchase/receipt/createpurchasereceipthandler.go @@ -0,0 +1,28 @@ +package receipt + +import ( + "net/http" + + "github.com/zeromicro/go-zero/rest/httpx" + "muyu-apiserver/gateway/internal/logic/purchase/receipt" + "muyu-apiserver/gateway/internal/svc" + "muyu-apiserver/gateway/internal/types" +) + +func CreatePurchaseReceiptHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.CreatePurchaseReceiptReq + if err := httpx.Parse(r, &req); err != nil { + httpx.ErrorCtx(r.Context(), w, err) + return + } + + l := receipt.NewCreatePurchaseReceiptLogic(r.Context(), svcCtx) + resp, err := l.CreatePurchaseReceipt(&req) + if err != nil { + httpx.ErrorCtx(r.Context(), w, err) + } else { + httpx.OkJsonCtx(r.Context(), w, resp) + } + } +} diff --git a/gateway/internal/handler/purchase/receipt/getpurchasereceipthandler.go b/gateway/internal/handler/purchase/receipt/getpurchasereceipthandler.go new file mode 100644 index 0000000..830e0bf --- /dev/null +++ b/gateway/internal/handler/purchase/receipt/getpurchasereceipthandler.go @@ -0,0 +1,21 @@ +package receipt + +import ( + "net/http" + + "github.com/zeromicro/go-zero/rest/httpx" + "muyu-apiserver/gateway/internal/logic/purchase/receipt" + "muyu-apiserver/gateway/internal/svc" +) + +func GetPurchaseReceiptHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + l := receipt.NewGetPurchaseReceiptLogic(r.Context(), svcCtx) + resp, err := l.GetPurchaseReceipt() + if err != nil { + httpx.ErrorCtx(r.Context(), w, err) + } else { + httpx.OkJsonCtx(r.Context(), w, resp) + } + } +} diff --git a/gateway/internal/handler/purchase/receipt/listpurchasereceipthandler.go b/gateway/internal/handler/purchase/receipt/listpurchasereceipthandler.go new file mode 100644 index 0000000..fc1966d --- /dev/null +++ b/gateway/internal/handler/purchase/receipt/listpurchasereceipthandler.go @@ -0,0 +1,28 @@ +package receipt + +import ( + "net/http" + + "github.com/zeromicro/go-zero/rest/httpx" + "muyu-apiserver/gateway/internal/logic/purchase/receipt" + "muyu-apiserver/gateway/internal/svc" + "muyu-apiserver/gateway/internal/types" +) + +func ListPurchaseReceiptHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.ListPurchaseReceiptReq + if err := httpx.Parse(r, &req); err != nil { + httpx.ErrorCtx(r.Context(), w, err) + return + } + + l := receipt.NewListPurchaseReceiptLogic(r.Context(), svcCtx) + resp, err := l.ListPurchaseReceipt(&req) + if err != nil { + httpx.ErrorCtx(r.Context(), w, err) + } else { + httpx.OkJsonCtx(r.Context(), w, resp) + } + } +} diff --git a/gateway/internal/handler/purchase/stats/getpurchasestatsbyproducthandler.go b/gateway/internal/handler/purchase/stats/getpurchasestatsbyproducthandler.go new file mode 100644 index 0000000..179c434 --- /dev/null +++ b/gateway/internal/handler/purchase/stats/getpurchasestatsbyproducthandler.go @@ -0,0 +1,28 @@ +package stats + +import ( + "net/http" + + "github.com/zeromicro/go-zero/rest/httpx" + "muyu-apiserver/gateway/internal/logic/purchase/stats" + "muyu-apiserver/gateway/internal/svc" + "muyu-apiserver/gateway/internal/types" +) + +func GetPurchaseStatsByProductHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.PurchaseStatsSummaryReq + if err := httpx.Parse(r, &req); err != nil { + httpx.ErrorCtx(r.Context(), w, err) + return + } + + l := stats.NewGetPurchaseStatsByProductLogic(r.Context(), svcCtx) + resp, err := l.GetPurchaseStatsByProduct(&req) + if err != nil { + httpx.ErrorCtx(r.Context(), w, err) + } else { + httpx.OkJsonCtx(r.Context(), w, resp) + } + } +} diff --git a/gateway/internal/handler/purchase/stats/getpurchasestatsbysupplierhandler.go b/gateway/internal/handler/purchase/stats/getpurchasestatsbysupplierhandler.go new file mode 100644 index 0000000..40c8c0b --- /dev/null +++ b/gateway/internal/handler/purchase/stats/getpurchasestatsbysupplierhandler.go @@ -0,0 +1,28 @@ +package stats + +import ( + "net/http" + + "github.com/zeromicro/go-zero/rest/httpx" + "muyu-apiserver/gateway/internal/logic/purchase/stats" + "muyu-apiserver/gateway/internal/svc" + "muyu-apiserver/gateway/internal/types" +) + +func GetPurchaseStatsBySupplierHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.PurchaseStatsSummaryReq + if err := httpx.Parse(r, &req); err != nil { + httpx.ErrorCtx(r.Context(), w, err) + return + } + + l := stats.NewGetPurchaseStatsBySupplierLogic(r.Context(), svcCtx) + resp, err := l.GetPurchaseStatsBySupplier(&req) + if err != nil { + httpx.ErrorCtx(r.Context(), w, err) + } else { + httpx.OkJsonCtx(r.Context(), w, resp) + } + } +} diff --git a/gateway/internal/handler/purchase/stats/getpurchasestatssummaryhandler.go b/gateway/internal/handler/purchase/stats/getpurchasestatssummaryhandler.go new file mode 100644 index 0000000..bd068ec --- /dev/null +++ b/gateway/internal/handler/purchase/stats/getpurchasestatssummaryhandler.go @@ -0,0 +1,28 @@ +package stats + +import ( + "net/http" + + "github.com/zeromicro/go-zero/rest/httpx" + "muyu-apiserver/gateway/internal/logic/purchase/stats" + "muyu-apiserver/gateway/internal/svc" + "muyu-apiserver/gateway/internal/types" +) + +func GetPurchaseStatsSummaryHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.PurchaseStatsSummaryReq + if err := httpx.Parse(r, &req); err != nil { + httpx.ErrorCtx(r.Context(), w, err) + return + } + + l := stats.NewGetPurchaseStatsSummaryLogic(r.Context(), svcCtx) + resp, err := l.GetPurchaseStatsSummary(&req) + if err != nil { + httpx.ErrorCtx(r.Context(), w, err) + } else { + httpx.OkJsonCtx(r.Context(), w, resp) + } + } +} diff --git a/gateway/internal/handler/purchase/supplier/createsupplierhandler.go b/gateway/internal/handler/purchase/supplier/createsupplierhandler.go new file mode 100644 index 0000000..4537a83 --- /dev/null +++ b/gateway/internal/handler/purchase/supplier/createsupplierhandler.go @@ -0,0 +1,28 @@ +package supplier + +import ( + "net/http" + + "github.com/zeromicro/go-zero/rest/httpx" + "muyu-apiserver/gateway/internal/logic/purchase/supplier" + "muyu-apiserver/gateway/internal/svc" + "muyu-apiserver/gateway/internal/types" +) + +func CreateSupplierHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.CreateSupplierReq + if err := httpx.Parse(r, &req); err != nil { + httpx.ErrorCtx(r.Context(), w, err) + return + } + + l := supplier.NewCreateSupplierLogic(r.Context(), svcCtx) + resp, err := l.CreateSupplier(&req) + if err != nil { + httpx.ErrorCtx(r.Context(), w, err) + } else { + httpx.OkJsonCtx(r.Context(), w, resp) + } + } +} diff --git a/gateway/internal/handler/purchase/supplier/deletesupplierhandler.go b/gateway/internal/handler/purchase/supplier/deletesupplierhandler.go new file mode 100644 index 0000000..ac1cee5 --- /dev/null +++ b/gateway/internal/handler/purchase/supplier/deletesupplierhandler.go @@ -0,0 +1,21 @@ +package supplier + +import ( + "net/http" + + "github.com/zeromicro/go-zero/rest/httpx" + "muyu-apiserver/gateway/internal/logic/purchase/supplier" + "muyu-apiserver/gateway/internal/svc" +) + +func DeleteSupplierHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + l := supplier.NewDeleteSupplierLogic(r.Context(), svcCtx) + err := l.DeleteSupplier() + if err != nil { + httpx.ErrorCtx(r.Context(), w, err) + } else { + httpx.OkJsonCtx(r.Context(), w, nil) + } + } +} diff --git a/gateway/internal/handler/purchase/supplier/getsupplierhandler.go b/gateway/internal/handler/purchase/supplier/getsupplierhandler.go new file mode 100644 index 0000000..11e10c3 --- /dev/null +++ b/gateway/internal/handler/purchase/supplier/getsupplierhandler.go @@ -0,0 +1,21 @@ +package supplier + +import ( + "net/http" + + "github.com/zeromicro/go-zero/rest/httpx" + "muyu-apiserver/gateway/internal/logic/purchase/supplier" + "muyu-apiserver/gateway/internal/svc" +) + +func GetSupplierHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + l := supplier.NewGetSupplierLogic(r.Context(), svcCtx) + resp, err := l.GetSupplier() + if err != nil { + httpx.ErrorCtx(r.Context(), w, err) + } else { + httpx.OkJsonCtx(r.Context(), w, resp) + } + } +} diff --git a/gateway/internal/handler/purchase/supplier/listsupplierhandler.go b/gateway/internal/handler/purchase/supplier/listsupplierhandler.go new file mode 100644 index 0000000..6f045e1 --- /dev/null +++ b/gateway/internal/handler/purchase/supplier/listsupplierhandler.go @@ -0,0 +1,28 @@ +package supplier + +import ( + "net/http" + + "github.com/zeromicro/go-zero/rest/httpx" + "muyu-apiserver/gateway/internal/logic/purchase/supplier" + "muyu-apiserver/gateway/internal/svc" + "muyu-apiserver/gateway/internal/types" +) + +func ListSupplierHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.ListSupplierReq + if err := httpx.Parse(r, &req); err != nil { + httpx.ErrorCtx(r.Context(), w, err) + return + } + + l := supplier.NewListSupplierLogic(r.Context(), svcCtx) + resp, err := l.ListSupplier(&req) + if err != nil { + httpx.ErrorCtx(r.Context(), w, err) + } else { + httpx.OkJsonCtx(r.Context(), w, resp) + } + } +} diff --git a/gateway/internal/handler/purchase/supplier/updatesupplierhandler.go b/gateway/internal/handler/purchase/supplier/updatesupplierhandler.go new file mode 100644 index 0000000..8c9c6bd --- /dev/null +++ b/gateway/internal/handler/purchase/supplier/updatesupplierhandler.go @@ -0,0 +1,28 @@ +package supplier + +import ( + "net/http" + + "github.com/zeromicro/go-zero/rest/httpx" + "muyu-apiserver/gateway/internal/logic/purchase/supplier" + "muyu-apiserver/gateway/internal/svc" + "muyu-apiserver/gateway/internal/types" +) + +func UpdateSupplierHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.UpdateSupplierReq + if err := httpx.Parse(r, &req); err != nil { + httpx.ErrorCtx(r.Context(), w, err) + return + } + + l := supplier.NewUpdateSupplierLogic(r.Context(), svcCtx) + err := l.UpdateSupplier(&req) + if err != nil { + httpx.ErrorCtx(r.Context(), w, err) + } else { + httpx.OkJsonCtx(r.Context(), w, nil) + } + } +} diff --git a/gateway/internal/handler/routes.go b/gateway/internal/handler/routes.go index 68ac1b9..c674731 100644 --- a/gateway/internal/handler/routes.go +++ b/gateway/internal/handler/routes.go @@ -10,9 +10,15 @@ import ( crmrelation "muyu-apiserver/gateway/internal/handler/crm/relation" inventoryadjust "muyu-apiserver/gateway/internal/handler/inventory/adjust" inventorycheck "muyu-apiserver/gateway/internal/handler/inventory/check" + inventorylog "muyu-apiserver/gateway/internal/handler/inventory/log" inventorypanbolt "muyu-apiserver/gateway/internal/handler/inventory/panbolt" inventoryproduct "muyu-apiserver/gateway/internal/handler/inventory/product" inventorystock "muyu-apiserver/gateway/internal/handler/inventory/stock" + purchaseorder "muyu-apiserver/gateway/internal/handler/purchase/order" + purchasepayment "muyu-apiserver/gateway/internal/handler/purchase/payment" + purchasereceipt "muyu-apiserver/gateway/internal/handler/purchase/receipt" + purchasestats "muyu-apiserver/gateway/internal/handler/purchase/stats" + purchasesupplier "muyu-apiserver/gateway/internal/handler/purchase/supplier" systemconfig "muyu-apiserver/gateway/internal/handler/system/config" systemlog "muyu-apiserver/gateway/internal/handler/system/log" systemmenu "muyu-apiserver/gateway/internal/handler/system/menu" @@ -463,4 +469,169 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { rest.WithJwt(serverCtx.Config.Auth.AccessSecret), rest.WithPrefix("/api/v1/system"), ) + + server.AddRoutes( + rest.WithMiddlewares( + []rest.Middleware{serverCtx.AuthorityMiddleware}, + []rest.Route{ + { + Method: http.MethodGet, + Path: "/suppliers", + Handler: purchasesupplier.ListSupplierHandler(serverCtx), + }, + { + Method: http.MethodPost, + Path: "/suppliers", + Handler: purchasesupplier.CreateSupplierHandler(serverCtx), + }, + { + Method: http.MethodGet, + Path: "/suppliers/:id", + Handler: purchasesupplier.GetSupplierHandler(serverCtx), + }, + { + Method: http.MethodPut, + Path: "/suppliers/:id", + Handler: purchasesupplier.UpdateSupplierHandler(serverCtx), + }, + { + Method: http.MethodDelete, + Path: "/suppliers/:id", + Handler: purchasesupplier.DeleteSupplierHandler(serverCtx), + }, + }..., + ), + rest.WithJwt(serverCtx.Config.Auth.AccessSecret), + rest.WithPrefix("/api/v1/purchase"), + ) + + server.AddRoutes( + rest.WithMiddlewares( + []rest.Middleware{serverCtx.AuthorityMiddleware}, + []rest.Route{ + { + Method: http.MethodGet, + Path: "/orders", + Handler: purchaseorder.ListPurchaseOrderHandler(serverCtx), + }, + { + Method: http.MethodPost, + Path: "/orders", + Handler: purchaseorder.CreatePurchaseOrderHandler(serverCtx), + }, + { + Method: http.MethodGet, + Path: "/orders/:id", + Handler: purchaseorder.GetPurchaseOrderHandler(serverCtx), + }, + { + Method: http.MethodPut, + Path: "/orders/:id", + Handler: purchaseorder.UpdatePurchaseOrderHandler(serverCtx), + }, + { + Method: http.MethodPost, + Path: "/orders/:id/confirm", + Handler: purchaseorder.ConfirmPurchaseOrderHandler(serverCtx), + }, + { + Method: http.MethodPost, + Path: "/orders/:id/cancel", + Handler: purchaseorder.CancelPurchaseOrderHandler(serverCtx), + }, + }..., + ), + rest.WithJwt(serverCtx.Config.Auth.AccessSecret), + rest.WithPrefix("/api/v1/purchase"), + ) + + server.AddRoutes( + rest.WithMiddlewares( + []rest.Middleware{serverCtx.AuthorityMiddleware}, + []rest.Route{ + { + Method: http.MethodGet, + Path: "/receipts", + Handler: purchasereceipt.ListPurchaseReceiptHandler(serverCtx), + }, + { + Method: http.MethodPost, + Path: "/receipts", + Handler: purchasereceipt.CreatePurchaseReceiptHandler(serverCtx), + }, + { + Method: http.MethodGet, + Path: "/receipts/:id", + Handler: purchasereceipt.GetPurchaseReceiptHandler(serverCtx), + }, + { + Method: http.MethodPost, + Path: "/receipts/:id/confirm", + Handler: purchasereceipt.ConfirmPurchaseReceiptHandler(serverCtx), + }, + }..., + ), + rest.WithJwt(serverCtx.Config.Auth.AccessSecret), + rest.WithPrefix("/api/v1/purchase"), + ) + + server.AddRoutes( + rest.WithMiddlewares( + []rest.Middleware{serverCtx.AuthorityMiddleware}, + []rest.Route{ + { + Method: http.MethodGet, + Path: "/payments", + Handler: purchasepayment.ListPurchasePaymentHandler(serverCtx), + }, + { + Method: http.MethodPost, + Path: "/payments", + Handler: purchasepayment.CreatePurchasePaymentHandler(serverCtx), + }, + }..., + ), + rest.WithJwt(serverCtx.Config.Auth.AccessSecret), + rest.WithPrefix("/api/v1/purchase"), + ) + + server.AddRoutes( + rest.WithMiddlewares( + []rest.Middleware{serverCtx.AuthorityMiddleware}, + []rest.Route{ + { + Method: http.MethodGet, + Path: "/stats/summary", + Handler: purchasestats.GetPurchaseStatsSummaryHandler(serverCtx), + }, + { + Method: http.MethodGet, + Path: "/stats/by-supplier", + Handler: purchasestats.GetPurchaseStatsBySupplierHandler(serverCtx), + }, + { + Method: http.MethodGet, + Path: "/stats/by-product", + Handler: purchasestats.GetPurchaseStatsByProductHandler(serverCtx), + }, + }..., + ), + rest.WithJwt(serverCtx.Config.Auth.AccessSecret), + rest.WithPrefix("/api/v1/purchase"), + ) + + server.AddRoutes( + rest.WithMiddlewares( + []rest.Middleware{serverCtx.AuthorityMiddleware}, + []rest.Route{ + { + Method: http.MethodGet, + Path: "/logs", + Handler: inventorylog.ListInventoryLogHandler(serverCtx), + }, + }..., + ), + rest.WithJwt(serverCtx.Config.Auth.AccessSecret), + rest.WithPrefix("/api/v1/inventory"), + ) } diff --git a/gateway/internal/logic/inventory/log/listinventoryloglogic.go b/gateway/internal/logic/inventory/log/listinventoryloglogic.go new file mode 100644 index 0000000..24134a1 --- /dev/null +++ b/gateway/internal/logic/inventory/log/listinventoryloglogic.go @@ -0,0 +1,58 @@ +package log + +import ( + "context" + + "muyu-apiserver/gateway/internal/svc" + "muyu-apiserver/gateway/internal/types" + "muyu-apiserver/rpc/purchase/purchaseservice" + + "github.com/zeromicro/go-zero/core/logx" +) + +type ListInventoryLogLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewListInventoryLogLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ListInventoryLogLogic { + return &ListInventoryLogLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *ListInventoryLogLogic) ListInventoryLog(req *types.ListInventoryLogReq) (*types.ListInventoryLogResp, error) { + rpcResp, err := l.svcCtx.PurchaseRpc.ListInventoryLog(l.ctx, &purchaseservice.ListInventoryLogReq{ + Page: req.Page, + PageSize: req.PageSize, + ProductId: req.ProductId, + ChangeType: req.ChangeType, + StartDate: req.StartDate, + EndDate: req.EndDate, + }) + if err != nil { + return nil, err + } + + list := make([]types.InventoryLogInfo, 0, len(rpcResp.List)) + for _, item := range rpcResp.List { + list = append(list, types.InventoryLogInfo{ + LogId: item.LogId, + ProductId: item.ProductId, + ChangeQty: item.ChangeQty, + BalanceAfter: item.BalanceAfter, + ChangeType: item.ChangeType, + RefType: item.RefType, + RefId: item.RefId, + ContactId: item.ContactId, + LogDate: item.LogDate, + Operator: item.Operator, + Remark: item.Remark, + CreatedAt: item.CreatedAt, + }) + } + return &types.ListInventoryLogResp{Total: rpcResp.Total, List: list}, nil +} diff --git a/gateway/internal/logic/purchase/order/cancelpurchaseorderlogic.go b/gateway/internal/logic/purchase/order/cancelpurchaseorderlogic.go new file mode 100644 index 0000000..4b13fe1 --- /dev/null +++ b/gateway/internal/logic/purchase/order/cancelpurchaseorderlogic.go @@ -0,0 +1,33 @@ +package order + +import ( + "context" + + "muyu-apiserver/gateway/internal/svc" + "muyu-apiserver/pkg/ctxdata" + "muyu-apiserver/rpc/purchase/purchaseservice" + + "github.com/zeromicro/go-zero/core/logx" +) + +type CancelPurchaseOrderLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewCancelPurchaseOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CancelPurchaseOrderLogic { + return &CancelPurchaseOrderLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *CancelPurchaseOrderLogic) CancelPurchaseOrder() error { + id := ctxdata.GetPathId(l.ctx) + _, err := l.svcCtx.PurchaseRpc.CancelPurchaseOrder(l.ctx, &purchaseservice.CancelPurchaseOrderReq{ + OrderId: id, + }) + return err +} diff --git a/gateway/internal/logic/purchase/order/confirmpurchaseorderlogic.go b/gateway/internal/logic/purchase/order/confirmpurchaseorderlogic.go new file mode 100644 index 0000000..de906bc --- /dev/null +++ b/gateway/internal/logic/purchase/order/confirmpurchaseorderlogic.go @@ -0,0 +1,33 @@ +package order + +import ( + "context" + + "muyu-apiserver/gateway/internal/svc" + "muyu-apiserver/pkg/ctxdata" + "muyu-apiserver/rpc/purchase/purchaseservice" + + "github.com/zeromicro/go-zero/core/logx" +) + +type ConfirmPurchaseOrderLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewConfirmPurchaseOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ConfirmPurchaseOrderLogic { + return &ConfirmPurchaseOrderLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *ConfirmPurchaseOrderLogic) ConfirmPurchaseOrder() error { + id := ctxdata.GetPathId(l.ctx) + _, err := l.svcCtx.PurchaseRpc.ConfirmPurchaseOrder(l.ctx, &purchaseservice.ConfirmPurchaseOrderReq{ + OrderId: id, + }) + return err +} diff --git a/gateway/internal/logic/purchase/order/createpurchaseorderlogic.go b/gateway/internal/logic/purchase/order/createpurchaseorderlogic.go new file mode 100644 index 0000000..dc6b2c8 --- /dev/null +++ b/gateway/internal/logic/purchase/order/createpurchaseorderlogic.go @@ -0,0 +1,52 @@ +package order + +import ( + "context" + + "muyu-apiserver/gateway/internal/svc" + "muyu-apiserver/gateway/internal/types" + "muyu-apiserver/rpc/purchase/purchaseservice" + + "github.com/zeromicro/go-zero/core/logx" +) + +type CreatePurchaseOrderLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewCreatePurchaseOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreatePurchaseOrderLogic { + return &CreatePurchaseOrderLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *CreatePurchaseOrderLogic) CreatePurchaseOrder(req *types.CreatePurchaseOrderReq) (*types.IdResp, error) { + details := make([]*purchaseservice.PurchaseOrderDetailReq, 0, len(req.Details)) + for _, d := range req.Details { + details = append(details, &purchaseservice.PurchaseOrderDetailReq{ + ProductId: d.ProductId, + ProductName: d.ProductName, + Spec: d.Spec, + Color: d.Color, + Quantity: d.Quantity, + UnitPrice: d.UnitPrice, + Remark: d.Remark, + }) + } + + resp, err := l.svcCtx.PurchaseRpc.CreatePurchaseOrder(l.ctx, &purchaseservice.CreatePurchaseOrderReq{ + SupplierId: req.SupplierId, + OrderDate: req.OrderDate, + PurchaseBy: req.PurchaseBy, + Remark: req.Remark, + Details: details, + }) + if err != nil { + return nil, err + } + return &types.IdResp{Id: resp.Id}, nil +} diff --git a/gateway/internal/logic/purchase/order/getpurchaseorderlogic.go b/gateway/internal/logic/purchase/order/getpurchaseorderlogic.go new file mode 100644 index 0000000..961af9f --- /dev/null +++ b/gateway/internal/logic/purchase/order/getpurchaseorderlogic.go @@ -0,0 +1,37 @@ +package order + +import ( + "context" + + "muyu-apiserver/gateway/internal/svc" + "muyu-apiserver/gateway/internal/types" + "muyu-apiserver/pkg/ctxdata" + "muyu-apiserver/rpc/purchase/purchaseservice" + + "github.com/zeromicro/go-zero/core/logx" +) + +type GetPurchaseOrderLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewGetPurchaseOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetPurchaseOrderLogic { + return &GetPurchaseOrderLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *GetPurchaseOrderLogic) GetPurchaseOrder() (*types.PurchaseOrderInfo, error) { + id := ctxdata.GetPathId(l.ctx) + resp, err := l.svcCtx.PurchaseRpc.GetPurchaseOrder(l.ctx, &purchaseservice.GetPurchaseOrderReq{ + OrderId: id, + }) + if err != nil { + return nil, err + } + return purchaseOrderInfoFromPB(resp), nil +} diff --git a/gateway/internal/logic/purchase/order/listpurchaseorderlogic.go b/gateway/internal/logic/purchase/order/listpurchaseorderlogic.go new file mode 100644 index 0000000..8679f7a --- /dev/null +++ b/gateway/internal/logic/purchase/order/listpurchaseorderlogic.go @@ -0,0 +1,86 @@ +package order + +import ( + "context" + + "muyu-apiserver/gateway/internal/svc" + "muyu-apiserver/gateway/internal/types" + "muyu-apiserver/rpc/purchase/purchaseservice" + + "github.com/zeromicro/go-zero/core/logx" +) + +type ListPurchaseOrderLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewListPurchaseOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ListPurchaseOrderLogic { + return &ListPurchaseOrderLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *ListPurchaseOrderLogic) ListPurchaseOrder(req *types.ListPurchaseOrderReq) (*types.ListPurchaseOrderResp, error) { + rpcResp, err := l.svcCtx.PurchaseRpc.ListPurchaseOrder(l.ctx, &purchaseservice.ListPurchaseOrderReq{ + Page: req.Page, + PageSize: req.PageSize, + SupplierId: req.SupplierId, + Status: req.Status, + StartDate: req.StartDate, + EndDate: req.EndDate, + }) + if err != nil { + return nil, err + } + + list := make([]types.PurchaseOrderInfo, 0, len(rpcResp.List)) + for _, o := range rpcResp.List { + list = append(list, *purchaseOrderInfoFromPB(o)) + } + return &types.ListPurchaseOrderResp{Total: rpcResp.Total, List: list}, nil +} + +func purchaseOrderInfoFromPB(o *purchaseservice.PurchaseOrderInfo) *types.PurchaseOrderInfo { + if o == nil { + return &types.PurchaseOrderInfo{} + } + details := make([]types.PurchaseOrderDetailInfo, 0, len(o.Details)) + for _, d := range o.Details { + details = append(details, types.PurchaseOrderDetailInfo{ + DetailId: d.DetailId, + ProductId: d.ProductId, + ProductName: d.ProductName, + Spec: d.Spec, + Color: d.Color, + Quantity: d.Quantity, + UnitPrice: d.UnitPrice, + Amount: d.Amount, + ReceivedQty: d.ReceivedQty, + Remark: d.Remark, + }) + } + return &types.PurchaseOrderInfo{ + OrderId: o.OrderId, + OrderNo: o.OrderNo, + SupplierId: o.SupplierId, + SupplierName: o.SupplierName, + OrderDate: o.OrderDate, + ContractAmount: o.ContractAmount, + ReceivedQty: o.ReceivedQty, + PaidAmount: o.PaidAmount, + PaymentStatus: o.PaymentStatus, + ReceiptStatus: o.ReceiptStatus, + PurchaseBy: o.PurchaseBy, + Creator: o.Creator, + Operator: o.Operator, + Status: o.Status, + Remark: o.Remark, + CreatedAt: o.CreatedAt, + UpdatedAt: o.UpdatedAt, + Details: details, + } +} diff --git a/gateway/internal/logic/purchase/order/updatepurchaseorderlogic.go b/gateway/internal/logic/purchase/order/updatepurchaseorderlogic.go new file mode 100644 index 0000000..64c6825 --- /dev/null +++ b/gateway/internal/logic/purchase/order/updatepurchaseorderlogic.go @@ -0,0 +1,53 @@ +package order + +import ( + "context" + + "muyu-apiserver/gateway/internal/svc" + "muyu-apiserver/gateway/internal/types" + "muyu-apiserver/pkg/ctxdata" + "muyu-apiserver/rpc/purchase/purchaseservice" + + "github.com/zeromicro/go-zero/core/logx" +) + +type UpdatePurchaseOrderLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewUpdatePurchaseOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdatePurchaseOrderLogic { + return &UpdatePurchaseOrderLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *UpdatePurchaseOrderLogic) UpdatePurchaseOrder(req *types.UpdatePurchaseOrderReq) error { + id := ctxdata.GetPathId(l.ctx) + + details := make([]*purchaseservice.PurchaseOrderDetailReq, 0, len(req.Details)) + for _, d := range req.Details { + details = append(details, &purchaseservice.PurchaseOrderDetailReq{ + ProductId: d.ProductId, + ProductName: d.ProductName, + Spec: d.Spec, + Color: d.Color, + Quantity: d.Quantity, + UnitPrice: d.UnitPrice, + Remark: d.Remark, + }) + } + + _, err := l.svcCtx.PurchaseRpc.UpdatePurchaseOrder(l.ctx, &purchaseservice.UpdatePurchaseOrderReq{ + OrderId: id, + SupplierId: req.SupplierId, + OrderDate: req.OrderDate, + PurchaseBy: req.PurchaseBy, + Remark: req.Remark, + Details: details, + }) + return err +} diff --git a/gateway/internal/logic/purchase/payment/createpurchasepaymentlogic.go b/gateway/internal/logic/purchase/payment/createpurchasepaymentlogic.go new file mode 100644 index 0000000..928bbaa --- /dev/null +++ b/gateway/internal/logic/purchase/payment/createpurchasepaymentlogic.go @@ -0,0 +1,39 @@ +package payment + +import ( + "context" + + "muyu-apiserver/gateway/internal/svc" + "muyu-apiserver/gateway/internal/types" + "muyu-apiserver/rpc/purchase/purchaseservice" + + "github.com/zeromicro/go-zero/core/logx" +) + +type CreatePurchasePaymentLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewCreatePurchasePaymentLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreatePurchasePaymentLogic { + return &CreatePurchasePaymentLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *CreatePurchasePaymentLogic) CreatePurchasePayment(req *types.CreatePurchasePaymentReq) (*types.IdResp, error) { + resp, err := l.svcCtx.PurchaseRpc.CreatePurchasePayment(l.ctx, &purchaseservice.CreatePurchasePaymentReq{ + OrderId: req.OrderId, + PaymentDate: req.PaymentDate, + Amount: req.Amount, + PaymentMethod: req.PaymentMethod, + Remark: req.Remark, + }) + if err != nil { + return nil, err + } + return &types.IdResp{Id: resp.Id}, nil +} diff --git a/gateway/internal/logic/purchase/payment/listpurchasepaymentlogic.go b/gateway/internal/logic/purchase/payment/listpurchasepaymentlogic.go new file mode 100644 index 0000000..ad30501 --- /dev/null +++ b/gateway/internal/logic/purchase/payment/listpurchasepaymentlogic.go @@ -0,0 +1,54 @@ +package payment + +import ( + "context" + + "muyu-apiserver/gateway/internal/svc" + "muyu-apiserver/gateway/internal/types" + "muyu-apiserver/rpc/purchase/purchaseservice" + + "github.com/zeromicro/go-zero/core/logx" +) + +type ListPurchasePaymentLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewListPurchasePaymentLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ListPurchasePaymentLogic { + return &ListPurchasePaymentLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *ListPurchasePaymentLogic) ListPurchasePayment(req *types.ListPurchasePaymentReq) (*types.ListPurchasePaymentResp, error) { + rpcResp, err := l.svcCtx.PurchaseRpc.ListPurchasePayment(l.ctx, &purchaseservice.ListPurchasePaymentReq{ + Page: req.Page, + PageSize: req.PageSize, + OrderId: req.OrderId, + StartDate: req.StartDate, + EndDate: req.EndDate, + }) + if err != nil { + return nil, err + } + + list := make([]types.PurchasePaymentInfo, 0, len(rpcResp.List)) + for _, p := range rpcResp.List { + list = append(list, types.PurchasePaymentInfo{ + PaymentId: p.PaymentId, + OrderId: p.OrderId, + SupplierId: p.SupplierId, + PaymentDate: p.PaymentDate, + Amount: p.Amount, + PaymentMethod: p.PaymentMethod, + Operator: p.Operator, + Remark: p.Remark, + CreatedAt: p.CreatedAt, + }) + } + return &types.ListPurchasePaymentResp{Total: rpcResp.Total, List: list}, nil +} diff --git a/gateway/internal/logic/purchase/receipt/confirmpurchasereceiptlogic.go b/gateway/internal/logic/purchase/receipt/confirmpurchasereceiptlogic.go new file mode 100644 index 0000000..f87690d --- /dev/null +++ b/gateway/internal/logic/purchase/receipt/confirmpurchasereceiptlogic.go @@ -0,0 +1,33 @@ +package receipt + +import ( + "context" + + "muyu-apiserver/gateway/internal/svc" + "muyu-apiserver/pkg/ctxdata" + "muyu-apiserver/rpc/purchase/purchaseservice" + + "github.com/zeromicro/go-zero/core/logx" +) + +type ConfirmPurchaseReceiptLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewConfirmPurchaseReceiptLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ConfirmPurchaseReceiptLogic { + return &ConfirmPurchaseReceiptLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *ConfirmPurchaseReceiptLogic) ConfirmPurchaseReceipt() error { + id := ctxdata.GetPathId(l.ctx) + _, err := l.svcCtx.PurchaseRpc.ConfirmPurchaseReceipt(l.ctx, &purchaseservice.ConfirmPurchaseReceiptReq{ + ReceiptId: id, + }) + return err +} diff --git a/gateway/internal/logic/purchase/receipt/createpurchasereceiptlogic.go b/gateway/internal/logic/purchase/receipt/createpurchasereceiptlogic.go new file mode 100644 index 0000000..2d9bbfd --- /dev/null +++ b/gateway/internal/logic/purchase/receipt/createpurchasereceiptlogic.go @@ -0,0 +1,50 @@ +package receipt + +import ( + "context" + + "muyu-apiserver/gateway/internal/svc" + "muyu-apiserver/gateway/internal/types" + "muyu-apiserver/rpc/purchase/purchaseservice" + + "github.com/zeromicro/go-zero/core/logx" +) + +type CreatePurchaseReceiptLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewCreatePurchaseReceiptLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreatePurchaseReceiptLogic { + return &CreatePurchaseReceiptLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *CreatePurchaseReceiptLogic) CreatePurchaseReceipt(req *types.CreatePurchaseReceiptReq) (*types.IdResp, error) { + details := make([]*purchaseservice.PurchaseReceiptDetailReq, 0, len(req.Details)) + for _, d := range req.Details { + details = append(details, &purchaseservice.PurchaseReceiptDetailReq{ + OrderDetailId: d.OrderDetailId, + ProductId: d.ProductId, + ActualQty: d.ActualQty, + UnitCost: d.UnitCost, + Remark: d.Remark, + }) + } + + resp, err := l.svcCtx.PurchaseRpc.CreatePurchaseReceipt(l.ctx, &purchaseservice.CreatePurchaseReceiptReq{ + OrderId: req.OrderId, + ReceiptDate: req.ReceiptDate, + ReceivedBy: req.ReceivedBy, + Remark: req.Remark, + Details: details, + }) + if err != nil { + return nil, err + } + return &types.IdResp{Id: resp.Id}, nil +} diff --git a/gateway/internal/logic/purchase/receipt/getpurchasereceiptlogic.go b/gateway/internal/logic/purchase/receipt/getpurchasereceiptlogic.go new file mode 100644 index 0000000..2be3f21 --- /dev/null +++ b/gateway/internal/logic/purchase/receipt/getpurchasereceiptlogic.go @@ -0,0 +1,37 @@ +package receipt + +import ( + "context" + + "muyu-apiserver/gateway/internal/svc" + "muyu-apiserver/gateway/internal/types" + "muyu-apiserver/pkg/ctxdata" + "muyu-apiserver/rpc/purchase/purchaseservice" + + "github.com/zeromicro/go-zero/core/logx" +) + +type GetPurchaseReceiptLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewGetPurchaseReceiptLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetPurchaseReceiptLogic { + return &GetPurchaseReceiptLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *GetPurchaseReceiptLogic) GetPurchaseReceipt() (*types.PurchaseReceiptInfo, error) { + id := ctxdata.GetPathId(l.ctx) + resp, err := l.svcCtx.PurchaseRpc.GetPurchaseReceipt(l.ctx, &purchaseservice.GetPurchaseReceiptReq{ + ReceiptId: id, + }) + if err != nil { + return nil, err + } + return purchaseReceiptInfoFromPB(resp), nil +} diff --git a/gateway/internal/logic/purchase/receipt/listpurchasereceiptlogic.go b/gateway/internal/logic/purchase/receipt/listpurchasereceiptlogic.go new file mode 100644 index 0000000..67d74a5 --- /dev/null +++ b/gateway/internal/logic/purchase/receipt/listpurchasereceiptlogic.go @@ -0,0 +1,73 @@ +package receipt + +import ( + "context" + + "muyu-apiserver/gateway/internal/svc" + "muyu-apiserver/gateway/internal/types" + "muyu-apiserver/rpc/purchase/purchaseservice" + + "github.com/zeromicro/go-zero/core/logx" +) + +type ListPurchaseReceiptLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewListPurchaseReceiptLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ListPurchaseReceiptLogic { + return &ListPurchaseReceiptLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *ListPurchaseReceiptLogic) ListPurchaseReceipt(req *types.ListPurchaseReceiptReq) (*types.ListPurchaseReceiptResp, error) { + rpcResp, err := l.svcCtx.PurchaseRpc.ListPurchaseReceipt(l.ctx, &purchaseservice.ListPurchaseReceiptReq{ + Page: req.Page, + PageSize: req.PageSize, + OrderId: req.OrderId, + Status: req.Status, + StartDate: req.StartDate, + EndDate: req.EndDate, + }) + if err != nil { + return nil, err + } + + list := make([]types.PurchaseReceiptInfo, 0, len(rpcResp.List)) + for _, r := range rpcResp.List { + list = append(list, *purchaseReceiptInfoFromPB(r)) + } + return &types.ListPurchaseReceiptResp{Total: rpcResp.Total, List: list}, nil +} + +func purchaseReceiptInfoFromPB(r *purchaseservice.PurchaseReceiptInfo) *types.PurchaseReceiptInfo { + if r == nil { + return &types.PurchaseReceiptInfo{} + } + details := make([]types.PurchaseReceiptDetailInfo, 0, len(r.Details)) + for _, d := range r.Details { + details = append(details, types.PurchaseReceiptDetailInfo{ + DetailId: d.DetailId, + OrderDetailId: d.OrderDetailId, + ProductId: d.ProductId, + ActualQty: d.ActualQty, + UnitCost: d.UnitCost, + Remark: d.Remark, + }) + } + return &types.PurchaseReceiptInfo{ + ReceiptId: r.ReceiptId, + ReceiptNo: r.ReceiptNo, + OrderId: r.OrderId, + ReceiptDate: r.ReceiptDate, + ReceivedBy: r.ReceivedBy, + Status: r.Status, + Remark: r.Remark, + CreatedAt: r.CreatedAt, + Details: details, + } +} diff --git a/gateway/internal/logic/purchase/stats/getpurchasestatsbyproductlogic.go b/gateway/internal/logic/purchase/stats/getpurchasestatsbyproductlogic.go new file mode 100644 index 0000000..7412ae0 --- /dev/null +++ b/gateway/internal/logic/purchase/stats/getpurchasestatsbyproductlogic.go @@ -0,0 +1,49 @@ +package stats + +import ( + "context" + + "muyu-apiserver/gateway/internal/svc" + "muyu-apiserver/gateway/internal/types" + "muyu-apiserver/rpc/purchase/purchaseservice" + + "github.com/zeromicro/go-zero/core/logx" +) + +type GetPurchaseStatsByProductLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewGetPurchaseStatsByProductLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetPurchaseStatsByProductLogic { + return &GetPurchaseStatsByProductLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *GetPurchaseStatsByProductLogic) GetPurchaseStatsByProduct(req *types.PurchaseStatsSummaryReq) (*types.PurchaseStatsByProductResp, error) { + resp, err := l.svcCtx.PurchaseRpc.GetPurchaseStatsByProduct(l.ctx, &purchaseservice.PurchaseStatsSummaryReq{ + StartDate: req.StartDate, + EndDate: req.EndDate, + }) + if err != nil { + return nil, err + } + + list := make([]types.PurchaseStatsByProductItem, 0, len(resp.List)) + for _, p := range resp.List { + list = append(list, types.PurchaseStatsByProductItem{ + ProductId: p.ProductId, + ProductName: p.ProductName, + Spec: p.Spec, + Color: p.Color, + TotalQty: p.TotalQty, + AvgUnitPrice: p.AvgUnitPrice, + TotalAmount: p.TotalAmount, + }) + } + return &types.PurchaseStatsByProductResp{List: list}, nil +} diff --git a/gateway/internal/logic/purchase/stats/getpurchasestatsbysupplierlogic.go b/gateway/internal/logic/purchase/stats/getpurchasestatsbysupplierlogic.go new file mode 100644 index 0000000..e742e63 --- /dev/null +++ b/gateway/internal/logic/purchase/stats/getpurchasestatsbysupplierlogic.go @@ -0,0 +1,47 @@ +package stats + +import ( + "context" + + "muyu-apiserver/gateway/internal/svc" + "muyu-apiserver/gateway/internal/types" + "muyu-apiserver/rpc/purchase/purchaseservice" + + "github.com/zeromicro/go-zero/core/logx" +) + +type GetPurchaseStatsBySupplierLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewGetPurchaseStatsBySupplierLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetPurchaseStatsBySupplierLogic { + return &GetPurchaseStatsBySupplierLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *GetPurchaseStatsBySupplierLogic) GetPurchaseStatsBySupplier(req *types.PurchaseStatsSummaryReq) (*types.PurchaseStatsBySupplierResp, error) { + resp, err := l.svcCtx.PurchaseRpc.GetPurchaseStatsBySupplier(l.ctx, &purchaseservice.PurchaseStatsSummaryReq{ + StartDate: req.StartDate, + EndDate: req.EndDate, + }) + if err != nil { + return nil, err + } + + list := make([]types.PurchaseStatsBySupplierItem, 0, len(resp.List)) + for _, s := range resp.List { + list = append(list, types.PurchaseStatsBySupplierItem{ + SupplierId: s.SupplierId, + SupplierName: s.SupplierName, + OrderCount: s.OrderCount, + TotalAmount: s.PurchaseAmount, + PaidAmount: s.PaidAmount, + }) + } + return &types.PurchaseStatsBySupplierResp{List: list}, nil +} diff --git a/gateway/internal/logic/purchase/stats/getpurchasestatssummarylogic.go b/gateway/internal/logic/purchase/stats/getpurchasestatssummarylogic.go new file mode 100644 index 0000000..19e190e --- /dev/null +++ b/gateway/internal/logic/purchase/stats/getpurchasestatssummarylogic.go @@ -0,0 +1,41 @@ +package stats + +import ( + "context" + + "muyu-apiserver/gateway/internal/svc" + "muyu-apiserver/gateway/internal/types" + "muyu-apiserver/rpc/purchase/purchaseservice" + + "github.com/zeromicro/go-zero/core/logx" +) + +type GetPurchaseStatsSummaryLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewGetPurchaseStatsSummaryLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetPurchaseStatsSummaryLogic { + return &GetPurchaseStatsSummaryLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *GetPurchaseStatsSummaryLogic) GetPurchaseStatsSummary(req *types.PurchaseStatsSummaryReq) (*types.PurchaseStatsSummaryResp, error) { + resp, err := l.svcCtx.PurchaseRpc.GetPurchaseStatsSummary(l.ctx, &purchaseservice.PurchaseStatsSummaryReq{ + StartDate: req.StartDate, + EndDate: req.EndDate, + }) + if err != nil { + return nil, err + } + return &types.PurchaseStatsSummaryResp{ + TotalOrders: resp.OrderCount, + TotalAmount: resp.TotalPurchaseAmount, + TotalPaidAmount: resp.TotalPaidAmount, + UnpaidAmount: resp.TotalUnpaidAmount, + }, nil +} diff --git a/gateway/internal/logic/purchase/supplier/createsupplierlogic.go b/gateway/internal/logic/purchase/supplier/createsupplierlogic.go new file mode 100644 index 0000000..3943165 --- /dev/null +++ b/gateway/internal/logic/purchase/supplier/createsupplierlogic.go @@ -0,0 +1,37 @@ +package supplier + +import ( + "context" + + "muyu-apiserver/gateway/internal/svc" + "muyu-apiserver/gateway/internal/types" + "muyu-apiserver/rpc/purchase/purchaseservice" + + "github.com/zeromicro/go-zero/core/logx" +) + +type CreateSupplierLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewCreateSupplierLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateSupplierLogic { + return &CreateSupplierLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *CreateSupplierLogic) CreateSupplier(req *types.CreateSupplierReq) (*types.IdResp, error) { + resp, err := l.svcCtx.PurchaseRpc.CreateSupplier(l.ctx, &purchaseservice.CreateSupplierReq{ + SupplierName: req.SupplierName, + Phone: req.Phone, + Remark: req.Remark, + }) + if err != nil { + return nil, err + } + return &types.IdResp{Id: resp.Id}, nil +} diff --git a/gateway/internal/logic/purchase/supplier/deletesupplierlogic.go b/gateway/internal/logic/purchase/supplier/deletesupplierlogic.go new file mode 100644 index 0000000..a0bfc05 --- /dev/null +++ b/gateway/internal/logic/purchase/supplier/deletesupplierlogic.go @@ -0,0 +1,33 @@ +package supplier + +import ( + "context" + + "muyu-apiserver/gateway/internal/svc" + "muyu-apiserver/pkg/ctxdata" + "muyu-apiserver/rpc/purchase/purchaseservice" + + "github.com/zeromicro/go-zero/core/logx" +) + +type DeleteSupplierLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewDeleteSupplierLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DeleteSupplierLogic { + return &DeleteSupplierLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *DeleteSupplierLogic) DeleteSupplier() error { + id := ctxdata.GetPathId(l.ctx) + _, err := l.svcCtx.PurchaseRpc.DeleteSupplier(l.ctx, &purchaseservice.DeleteSupplierReq{ + SupplierId: id, + }) + return err +} diff --git a/gateway/internal/logic/purchase/supplier/getsupplierlogic.go b/gateway/internal/logic/purchase/supplier/getsupplierlogic.go new file mode 100644 index 0000000..8f42aa6 --- /dev/null +++ b/gateway/internal/logic/purchase/supplier/getsupplierlogic.go @@ -0,0 +1,37 @@ +package supplier + +import ( + "context" + + "muyu-apiserver/gateway/internal/svc" + "muyu-apiserver/gateway/internal/types" + "muyu-apiserver/pkg/ctxdata" + "muyu-apiserver/rpc/purchase/purchaseservice" + + "github.com/zeromicro/go-zero/core/logx" +) + +type GetSupplierLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewGetSupplierLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetSupplierLogic { + return &GetSupplierLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *GetSupplierLogic) GetSupplier() (*types.SupplierInfo, error) { + id := ctxdata.GetPathId(l.ctx) + resp, err := l.svcCtx.PurchaseRpc.GetSupplier(l.ctx, &purchaseservice.GetSupplierReq{ + SupplierId: id, + }) + if err != nil { + return nil, err + } + return supplierInfoFromPB(resp), nil +} diff --git a/gateway/internal/logic/purchase/supplier/listsupplierlogic.go b/gateway/internal/logic/purchase/supplier/listsupplierlogic.go new file mode 100644 index 0000000..224d4eb --- /dev/null +++ b/gateway/internal/logic/purchase/supplier/listsupplierlogic.go @@ -0,0 +1,62 @@ +package supplier + +import ( + "context" + + "muyu-apiserver/gateway/internal/svc" + "muyu-apiserver/gateway/internal/types" + "muyu-apiserver/rpc/purchase/purchaseservice" + + "github.com/zeromicro/go-zero/core/logx" +) + +type ListSupplierLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewListSupplierLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ListSupplierLogic { + return &ListSupplierLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *ListSupplierLogic) ListSupplier(req *types.ListSupplierReq) (*types.ListSupplierResp, error) { + rpcResp, err := l.svcCtx.PurchaseRpc.ListSupplier(l.ctx, &purchaseservice.ListSupplierReq{ + Page: req.Page, + PageSize: req.PageSize, + SupplierName: req.SupplierName, + Status: req.Status, + }) + if err != nil { + return nil, err + } + + list := make([]types.SupplierInfo, 0, len(rpcResp.List)) + for _, s := range rpcResp.List { + list = append(list, *supplierInfoFromPB(s)) + } + return &types.ListSupplierResp{Total: rpcResp.Total, List: list}, nil +} + +func supplierInfoFromPB(s *purchaseservice.SupplierInfo) *types.SupplierInfo { + if s == nil { + return &types.SupplierInfo{} + } + return &types.SupplierInfo{ + SupplierId: s.SupplierId, + SupplierName: s.SupplierName, + Phone: s.Phone, + PurchaseCount: s.PurchaseCount, + DeliveredQty: s.DeliveredQty, + PayableAmount: s.PayableAmount, + PaidAmount: s.PaidAmount, + Status: s.Status, + Remark: s.Remark, + CreatedAt: s.CreatedAt, + UpdatedAt: s.UpdatedAt, + } +} diff --git a/gateway/internal/logic/purchase/supplier/updatesupplierlogic.go b/gateway/internal/logic/purchase/supplier/updatesupplierlogic.go new file mode 100644 index 0000000..7880f5a --- /dev/null +++ b/gateway/internal/logic/purchase/supplier/updatesupplierlogic.go @@ -0,0 +1,38 @@ +package supplier + +import ( + "context" + + "muyu-apiserver/gateway/internal/svc" + "muyu-apiserver/gateway/internal/types" + "muyu-apiserver/pkg/ctxdata" + "muyu-apiserver/rpc/purchase/purchaseservice" + + "github.com/zeromicro/go-zero/core/logx" +) + +type UpdateSupplierLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewUpdateSupplierLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateSupplierLogic { + return &UpdateSupplierLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *UpdateSupplierLogic) UpdateSupplier(req *types.UpdateSupplierReq) error { + id := ctxdata.GetPathId(l.ctx) + _, err := l.svcCtx.PurchaseRpc.UpdateSupplier(l.ctx, &purchaseservice.UpdateSupplierReq{ + SupplierId: id, + SupplierName: req.SupplierName, + Phone: req.Phone, + Status: req.Status, + Remark: req.Remark, + }) + return err +} diff --git a/gateway/internal/svc/serviceContext.go b/gateway/internal/svc/serviceContext.go index 038c5c8..f502e3e 100644 --- a/gateway/internal/svc/serviceContext.go +++ b/gateway/internal/svc/serviceContext.go @@ -13,6 +13,7 @@ import ( pkgcasbin "muyu-apiserver/pkg/casbin" "muyu-apiserver/pkg/tenantctx" "muyu-apiserver/rpc/inventory/inventoryservice" + "muyu-apiserver/rpc/purchase/purchaseservice" "muyu-apiserver/rpc/system/systemservice" ) @@ -23,6 +24,7 @@ type ServiceContext struct { CrmRepo *repo.CrmRepo SystemRpc systemservice.SystemService InventoryRpc inventoryservice.InventoryService + PurchaseRpc purchaseservice.PurchaseService } func NewServiceContext(c config.Config) *ServiceContext { @@ -59,5 +61,6 @@ func NewServiceContext(c config.Config) *ServiceContext { CrmRepo: repo.NewCrmRepo(pgConn), SystemRpc: systemservice.NewSystemService(zrpc.MustNewClient(c.SystemRpc, zrpc.WithUnaryClientInterceptor(tenantctx.UnaryClientInterceptor()))), InventoryRpc: inventoryservice.NewInventoryService(zrpc.MustNewClient(c.InventoryRpc, zrpc.WithUnaryClientInterceptor(tenantctx.UnaryClientInterceptor()))), + PurchaseRpc: purchaseservice.NewPurchaseService(zrpc.MustNewClient(c.PurchaseRpc, zrpc.WithUnaryClientInterceptor(tenantctx.UnaryClientInterceptor()))), } } diff --git a/gateway/internal/types/types.go b/gateway/internal/types/types.go index 3839246..60ecbc1 100644 --- a/gateway/internal/types/types.go +++ b/gateway/internal/types/types.go @@ -581,3 +581,281 @@ type CrmRelationHistoryResp struct { Total int64 `json:"total"` List []CrmRelationHistoryItem `json:"list"` } + +// ─── Supplier ──────────────────────────────────────────────────────────────── + +type SupplierInfo struct { + SupplierId string `json:"supplierId"` + SupplierName string `json:"supplierName"` + Phone string `json:"phone"` + PurchaseCount int64 `json:"purchaseCount"` + DeliveredQty string `json:"deliveredQty"` + PayableAmount string `json:"payableAmount"` + PaidAmount string `json:"paidAmount"` + Status int64 `json:"status"` + Remark string `json:"remark"` + CreatedAt string `json:"createdAt"` + UpdatedAt string `json:"updatedAt"` +} + +type CreateSupplierReq struct { + SupplierName string `json:"supplierName"` + Phone string `json:"phone,optional"` + Remark string `json:"remark,optional"` +} + +type UpdateSupplierReq struct { + SupplierName string `json:"supplierName,optional"` + Phone string `json:"phone,optional"` + Status int64 `json:"status,optional"` + Remark string `json:"remark,optional"` +} + +type ListSupplierReq struct { + Page int64 `form:"page,default=1"` + PageSize int64 `form:"pageSize,default=20"` + SupplierName string `form:"supplierName,optional"` + Status int64 `form:"status,optional,default=-1"` +} + +type ListSupplierResp struct { + Total int64 `json:"total"` + List []SupplierInfo `json:"list"` +} + +// ─── Purchase Order ────────────────────────────────────────────────────────── + +type PurchaseOrderDetailInfo struct { + DetailId string `json:"detailId"` + ProductId string `json:"productId"` + ProductName string `json:"productName"` + Spec string `json:"spec"` + Color string `json:"color"` + Quantity string `json:"quantity"` + UnitPrice string `json:"unitPrice"` + Amount string `json:"amount"` + ReceivedQty string `json:"receivedQty"` + Remark string `json:"remark"` +} + +type PurchaseOrderDetailReq struct { + ProductId string `json:"productId"` + ProductName string `json:"productName"` + Spec string `json:"spec,optional"` + Color string `json:"color,optional"` + Quantity string `json:"quantity"` + UnitPrice string `json:"unitPrice"` + Remark string `json:"remark,optional"` +} + +type PurchaseOrderInfo struct { + OrderId string `json:"orderId"` + OrderNo string `json:"orderNo"` + SupplierId string `json:"supplierId"` + SupplierName string `json:"supplierName"` + OrderDate string `json:"orderDate"` + ContractAmount string `json:"contractAmount"` + ReceivedQty string `json:"receivedQty"` + PaidAmount string `json:"paidAmount"` + PaymentStatus int64 `json:"paymentStatus"` + ReceiptStatus int64 `json:"receiptStatus"` + PurchaseBy string `json:"purchaseBy"` + Creator string `json:"creator"` + Operator string `json:"operator"` + Status int64 `json:"status"` + Remark string `json:"remark"` + CreatedAt string `json:"createdAt"` + UpdatedAt string `json:"updatedAt"` + Details []PurchaseOrderDetailInfo `json:"details"` +} + +type CreatePurchaseOrderReq struct { + SupplierId string `json:"supplierId"` + OrderDate string `json:"orderDate"` + PurchaseBy string `json:"purchaseBy,optional"` + Remark string `json:"remark,optional"` + Details []PurchaseOrderDetailReq `json:"details"` +} + +type UpdatePurchaseOrderReq struct { + SupplierId string `json:"supplierId,optional"` + OrderDate string `json:"orderDate,optional"` + PurchaseBy string `json:"purchaseBy,optional"` + Remark string `json:"remark,optional"` + Details []PurchaseOrderDetailReq `json:"details,optional"` +} + +type ListPurchaseOrderReq struct { + Page int64 `form:"page,default=1"` + PageSize int64 `form:"pageSize,default=20"` + SupplierId string `form:"supplierId,optional"` + Status int64 `form:"status,optional,default=-1"` + StartDate string `form:"startDate,optional"` + EndDate string `form:"endDate,optional"` +} + +type ListPurchaseOrderResp struct { + Total int64 `json:"total"` + List []PurchaseOrderInfo `json:"list"` +} + +// ─── Purchase Receipt ──────────────────────────────────────────────────────── + +type PurchaseReceiptDetailInfo struct { + DetailId string `json:"detailId"` + OrderDetailId string `json:"orderDetailId"` + ProductId string `json:"productId"` + ActualQty string `json:"actualQty"` + UnitCost string `json:"unitCost"` + Remark string `json:"remark"` +} + +type PurchaseReceiptDetailReq struct { + OrderDetailId string `json:"orderDetailId"` + ProductId string `json:"productId"` + ActualQty string `json:"actualQty"` + UnitCost string `json:"unitCost,optional"` + Remark string `json:"remark,optional"` +} + +type PurchaseReceiptInfo struct { + ReceiptId string `json:"receiptId"` + ReceiptNo string `json:"receiptNo"` + OrderId string `json:"orderId"` + ReceiptDate string `json:"receiptDate"` + ReceivedBy string `json:"receivedBy"` + Status int64 `json:"status"` + Remark string `json:"remark"` + CreatedAt string `json:"createdAt"` + Details []PurchaseReceiptDetailInfo `json:"details"` +} + +type CreatePurchaseReceiptReq struct { + OrderId string `json:"orderId"` + ReceiptDate string `json:"receiptDate"` + ReceivedBy string `json:"receivedBy,optional"` + Remark string `json:"remark,optional"` + Details []PurchaseReceiptDetailReq `json:"details"` +} + +type ListPurchaseReceiptReq struct { + Page int64 `form:"page,default=1"` + PageSize int64 `form:"pageSize,default=20"` + OrderId string `form:"orderId,optional"` + Status int64 `form:"status,optional,default=-1"` + StartDate string `form:"startDate,optional"` + EndDate string `form:"endDate,optional"` +} + +type ListPurchaseReceiptResp struct { + Total int64 `json:"total"` + List []PurchaseReceiptInfo `json:"list"` +} + +// ─── Purchase Payment ──────────────────────────────────────────────────────── + +type PurchasePaymentInfo struct { + PaymentId string `json:"paymentId"` + OrderId string `json:"orderId"` + SupplierId string `json:"supplierId"` + PaymentDate string `json:"paymentDate"` + Amount string `json:"amount"` + PaymentMethod string `json:"paymentMethod"` + Operator string `json:"operator"` + Remark string `json:"remark"` + CreatedAt string `json:"createdAt"` +} + +type CreatePurchasePaymentReq struct { + OrderId string `json:"orderId"` + PaymentDate string `json:"paymentDate"` + Amount string `json:"amount"` + PaymentMethod string `json:"paymentMethod,optional"` + Operator string `json:"operator,optional"` + Remark string `json:"remark,optional"` +} + +type ListPurchasePaymentReq struct { + Page int64 `form:"page,default=1"` + PageSize int64 `form:"pageSize,default=20"` + OrderId string `form:"orderId,optional"` + StartDate string `form:"startDate,optional"` + EndDate string `form:"endDate,optional"` +} + +type ListPurchasePaymentResp struct { + Total int64 `json:"total"` + List []PurchasePaymentInfo `json:"list"` +} + +// ─── Inventory Log ─────────────────────────────────────────────────────────── + +type InventoryLogInfo struct { + LogId string `json:"logId"` + ProductId string `json:"productId"` + ProductName string `json:"productName"` + ChangeQty string `json:"changeQty"` + BalanceAfter string `json:"balanceAfter"` + ChangeType int64 `json:"changeType"` + RefType string `json:"refType"` + RefId string `json:"refId"` + ContactId string `json:"contactId"` + LogDate string `json:"logDate"` + Operator string `json:"operator"` + Remark string `json:"remark"` + CreatedAt string `json:"createdAt"` +} + +type ListInventoryLogReq struct { + Page int64 `form:"page,default=1"` + PageSize int64 `form:"pageSize,default=20"` + ProductId string `form:"productId,optional"` + ChangeType int64 `form:"changeType,optional,default=-1"` + StartDate string `form:"startDate,optional"` + EndDate string `form:"endDate,optional"` +} + +type ListInventoryLogResp struct { + Total int64 `json:"total"` + List []InventoryLogInfo `json:"list"` +} + +// ─── Purchase Stats ────────────────────────────────────────────────────────── + +type PurchaseStatsSummaryReq struct { + StartDate string `form:"startDate,optional"` + EndDate string `form:"endDate,optional"` +} + +type PurchaseStatsSummaryResp struct { + TotalOrders int64 `json:"totalOrders"` + TotalAmount string `json:"totalAmount"` + TotalPaidAmount string `json:"totalPaidAmount"` + UnpaidAmount string `json:"unpaidAmount"` +} + +type PurchaseStatsBySupplierItem struct { + SupplierId string `json:"supplierId"` + SupplierName string `json:"supplierName"` + OrderCount int64 `json:"orderCount"` + TotalAmount string `json:"totalAmount"` + PaidAmount string `json:"paidAmount"` +} + +type PurchaseStatsBySupplierResp struct { + List []PurchaseStatsBySupplierItem `json:"list"` +} + +type PurchaseStatsByProductItem struct { + ProductId string `json:"productId"` + ProductName string `json:"productName"` + Spec string `json:"spec"` + Color string `json:"color"` + TotalQty string `json:"totalQty"` + AvgUnitPrice string `json:"avgUnitPrice"` + TotalAmount string `json:"totalAmount"` +} + +type PurchaseStatsByProductResp struct { + List []PurchaseStatsByProductItem `json:"list"` +} diff --git a/model/invproductmodel_gen.go b/model/invproductmodel_gen.go index 7fefa7c..3669189 100755 --- a/model/invproductmodel_gen.go +++ b/model/invproductmodel_gen.go @@ -52,6 +52,7 @@ type ( Spec string `db:"spec"` Color string `db:"color"` SalesPrice float64 `db:"sales_price"` + CostPrice float64 `db:"cost_price"` Remark sql.NullString `db:"remark"` Status int64 `db:"status"` TenantId string `db:"tenant_id"` @@ -146,8 +147,8 @@ func (m *defaultInvProductModel) Insert(ctx context.Context, data *InvProduct) ( invProductProductIdKey := fmt.Sprintf("%s%v", cacheInvProductProductIdPrefix, data.ProductId) invProductProductNameKey := fmt.Sprintf("%s%v", cacheInvProductProductNamePrefix, data.ProductName) ret, err := m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) { - query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", m.table, invProductRowsExpectAutoSet) - return conn.ExecCtx(ctx, query, data.ProductId, data.ProductName, data.ImageUrl, data.Spec, data.Color, data.SalesPrice, data.Remark, data.Status, data.TenantId, data.DeletedAt) + query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", m.table, invProductRowsExpectAutoSet) + return conn.ExecCtx(ctx, query, data.ProductId, data.ProductName, data.ImageUrl, data.Spec, data.Color, data.SalesPrice, data.CostPrice, data.Remark, data.Status, data.TenantId, data.DeletedAt) }, invProductIdKey, invProductProductIdKey, invProductProductNameKey) return ret, err } @@ -163,7 +164,7 @@ func (m *defaultInvProductModel) Update(ctx context.Context, newData *InvProduct invProductProductNameKey := fmt.Sprintf("%s%v", cacheInvProductProductNamePrefix, data.ProductName) _, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) { query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, invProductRowsWithPlaceHolder) - return conn.ExecCtx(ctx, query, newData.ProductId, newData.ProductName, newData.ImageUrl, newData.Spec, newData.Color, newData.SalesPrice, newData.Remark, newData.Status, newData.TenantId, newData.DeletedAt, newData.Id) + return conn.ExecCtx(ctx, query, newData.ProductId, newData.ProductName, newData.ImageUrl, newData.Spec, newData.Color, newData.SalesPrice, newData.CostPrice, newData.Remark, newData.Status, newData.TenantId, newData.DeletedAt, newData.Id) }, invProductIdKey, invProductProductIdKey, invProductProductNameKey) return err } diff --git a/model/invventorylogmodel.go b/model/invventorylogmodel.go new file mode 100644 index 0000000..9fda7fb --- /dev/null +++ b/model/invventorylogmodel.go @@ -0,0 +1,77 @@ +package model + +import ( + "context" + "fmt" + + "github.com/zeromicro/go-zero/core/stores/sqlx" +) + +var _ InvInventoryLogModel = (*customInvInventoryLogModel)(nil) + +type ( + InvInventoryLogModel interface { + invInventoryLogModel + FindList(ctx context.Context, tenantId string, page, pageSize int64, productId, refType string, changeType int64, startDate, endDate string) ([]*InvInventoryLog, int64, error) + FindByRefId(ctx context.Context, refId string) ([]*InvInventoryLog, error) + } + + customInvInventoryLogModel struct { + *defaultInvInventoryLogModel + } +) + +func NewInvInventoryLogModel(conn sqlx.SqlConn) InvInventoryLogModel { + return &customInvInventoryLogModel{ + defaultInvInventoryLogModel: newInvInventoryLogModel(conn), + } +} + +func (m *customInvInventoryLogModel) FindList(ctx context.Context, tenantId string, page, pageSize int64, productId, refType string, changeType int64, startDate, endDate string) ([]*InvInventoryLog, int64, error) { + where := "WHERE tenant_id = ?" + args := []interface{}{tenantId} + + if productId != "" { + where += " AND product_id = ?" + args = append(args, productId) + } + if refType != "" { + where += " AND ref_type = ?" + args = append(args, refType) + } + if changeType > 0 { + where += " AND change_type = ?" + args = append(args, changeType) + } + if startDate != "" { + where += " AND log_date >= ?" + args = append(args, startDate) + } + if endDate != "" { + where += " AND log_date <= ?" + args = append(args, endDate) + } + + var total int64 + countQuery := fmt.Sprintf("SELECT COUNT(*) FROM %s %s", m.table, where) + if err := m.conn.QueryRowCtx(ctx, &total, countQuery, args...); err != nil { + return nil, 0, err + } + + var list []*InvInventoryLog + query := fmt.Sprintf("SELECT %s FROM %s %s ORDER BY created_at DESC LIMIT ? OFFSET ?", invInventoryLogRows, m.table, where) + args = append(args, pageSize, (page-1)*pageSize) + if err := m.conn.QueryRowsCtx(ctx, &list, query, args...); err != nil { + return nil, 0, err + } + return list, total, nil +} + +func (m *customInvInventoryLogModel) FindByRefId(ctx context.Context, refId string) ([]*InvInventoryLog, error) { + var list []*InvInventoryLog + query := fmt.Sprintf("SELECT %s FROM %s WHERE ref_id = ? ORDER BY created_at DESC", invInventoryLogRows, m.table) + if err := m.conn.QueryRowsCtx(ctx, &list, query, refId); err != nil { + return nil, err + } + return list, nil +} diff --git a/model/invventorylogmodel_gen.go b/model/invventorylogmodel_gen.go new file mode 100644 index 0000000..5e050d4 --- /dev/null +++ b/model/invventorylogmodel_gen.go @@ -0,0 +1,102 @@ +package model + +import ( + "context" + "database/sql" + "fmt" + "strings" + "time" + + "github.com/zeromicro/go-zero/core/stores/builder" + "github.com/zeromicro/go-zero/core/stores/sqlx" + "github.com/zeromicro/go-zero/core/stringx" +) + +var ( + invInventoryLogFieldNames = builder.RawFieldNames(&InvInventoryLog{}) + invInventoryLogRows = strings.Join(invInventoryLogFieldNames, ",") + invInventoryLogRowsExpectAutoSet = strings.Join(stringx.Remove(invInventoryLogFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",") + invInventoryLogRowsWithPlaceHolder = strings.Join(stringx.Remove(invInventoryLogFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?" +) + +type ( + invInventoryLogModel interface { + Insert(ctx context.Context, data *InvInventoryLog) (sql.Result, error) + FindOne(ctx context.Context, id int64) (*InvInventoryLog, error) + FindOneByLogId(ctx context.Context, logId string) (*InvInventoryLog, error) + Update(ctx context.Context, data *InvInventoryLog) error + Delete(ctx context.Context, id int64) error + } + + defaultInvInventoryLogModel struct { + conn sqlx.SqlConn + table string + } + + InvInventoryLog struct { + Id int64 `db:"id"` + LogId string `db:"log_id"` + TenantId string `db:"tenant_id"` + ProductId string `db:"product_id"` + ChangeQty float64 `db:"change_qty"` + BalanceAfter float64 `db:"balance_after"` + ChangeType int64 `db:"change_type"` + RefType string `db:"ref_type"` + RefId string `db:"ref_id"` + ContactId string `db:"contact_id"` + LogDate time.Time `db:"log_date"` + Operator string `db:"operator"` + Remark sql.NullString `db:"remark"` + CreatedAt time.Time `db:"created_at"` + } +) + +func newInvInventoryLogModel(conn sqlx.SqlConn) *defaultInvInventoryLogModel { + return &defaultInvInventoryLogModel{ + conn: conn, + table: "`inv_inventory_log`", + } +} + +func (m *defaultInvInventoryLogModel) Insert(ctx context.Context, data *InvInventoryLog) (sql.Result, error) { + query := fmt.Sprintf("INSERT INTO %s (%s) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", m.table, invInventoryLogRowsExpectAutoSet) + return m.conn.ExecCtx(ctx, query, + data.LogId, data.TenantId, data.ProductId, data.ChangeQty, data.BalanceAfter, + data.ChangeType, data.RefType, data.RefId, data.ContactId, data.LogDate, data.Operator, data.Remark) +} + +func (m *defaultInvInventoryLogModel) FindOne(ctx context.Context, id int64) (*InvInventoryLog, error) { + query := fmt.Sprintf("SELECT %s FROM %s WHERE `id` = ? LIMIT 1", invInventoryLogRows, m.table) + var resp InvInventoryLog + if err := m.conn.QueryRowCtx(ctx, &resp, query, id); err != nil { + return nil, err + } + return &resp, nil +} + +func (m *defaultInvInventoryLogModel) FindOneByLogId(ctx context.Context, logId string) (*InvInventoryLog, error) { + query := fmt.Sprintf("SELECT %s FROM %s WHERE `log_id` = ? LIMIT 1", invInventoryLogRows, m.table) + var resp InvInventoryLog + if err := m.conn.QueryRowCtx(ctx, &resp, query, logId); err != nil { + return nil, err + } + return &resp, nil +} + +func (m *defaultInvInventoryLogModel) Update(ctx context.Context, data *InvInventoryLog) error { + query := fmt.Sprintf("UPDATE %s SET %s WHERE `id` = ?", m.table, invInventoryLogRowsWithPlaceHolder) + _, err := m.conn.ExecCtx(ctx, query, + data.LogId, data.TenantId, data.ProductId, data.ChangeQty, data.BalanceAfter, + data.ChangeType, data.RefType, data.RefId, data.ContactId, data.LogDate, data.Operator, data.Remark, data.Id) + return err +} + +func (m *defaultInvInventoryLogModel) Delete(ctx context.Context, id int64) error { + query := fmt.Sprintf("DELETE FROM %s WHERE `id` = ?", m.table) + _, err := m.conn.ExecCtx(ctx, query, id) + return err +} + +func (m *defaultInvInventoryLogModel) tableName() string { + return m.table +} diff --git a/model/purpurchaseorderdetailmodel.go b/model/purpurchaseorderdetailmodel.go new file mode 100644 index 0000000..0bf0c24 --- /dev/null +++ b/model/purpurchaseorderdetailmodel.go @@ -0,0 +1,69 @@ +package model + +import ( + "context" + "fmt" + "strings" + + "github.com/zeromicro/go-zero/core/stores/sqlx" +) + +var _ PurPurchaseOrderDetailModel = (*customPurPurchaseOrderDetailModel)(nil) + +type ( + PurPurchaseOrderDetailModel interface { + purPurchaseOrderDetailModel + FindByOrderId(ctx context.Context, orderId string) ([]*PurPurchaseOrderDetail, error) + DeleteByOrderId(ctx context.Context, orderId string) error + BulkInsert(ctx context.Context, details []*PurPurchaseOrderDetail) error + UpdateReceivedQty(ctx context.Context, detailId string, addQty float64) error + } + + customPurPurchaseOrderDetailModel struct { + *defaultPurPurchaseOrderDetailModel + } +) + +func NewPurPurchaseOrderDetailModel(conn sqlx.SqlConn) PurPurchaseOrderDetailModel { + return &customPurPurchaseOrderDetailModel{ + defaultPurPurchaseOrderDetailModel: newPurPurchaseOrderDetailModel(conn), + } +} + +func (m *customPurPurchaseOrderDetailModel) FindByOrderId(ctx context.Context, orderId string) ([]*PurPurchaseOrderDetail, error) { + var list []*PurPurchaseOrderDetail + query := fmt.Sprintf("SELECT %s FROM %s WHERE order_id = ?", purPurchaseOrderDetailRows, m.table) + if err := m.conn.QueryRowsCtx(ctx, &list, query, orderId); err != nil { + return nil, err + } + return list, nil +} + +func (m *customPurPurchaseOrderDetailModel) DeleteByOrderId(ctx context.Context, orderId string) error { + query := fmt.Sprintf("DELETE FROM %s WHERE order_id = ?", m.table) + _, err := m.conn.ExecCtx(ctx, query, orderId) + return err +} + +func (m *customPurPurchaseOrderDetailModel) BulkInsert(ctx context.Context, details []*PurPurchaseOrderDetail) error { + if len(details) == 0 { + return nil + } + placeholder := "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" + placeholders := make([]string, len(details)) + args := make([]interface{}, 0, len(details)*12) + for i, d := range details { + placeholders[i] = placeholder + args = append(args, d.DetailId, d.TenantId, d.OrderId, d.ProductId, d.ProductName, d.Spec, + d.Color, d.Quantity, d.UnitPrice, d.Amount, d.ReceivedQty, d.Remark) + } + query := fmt.Sprintf("INSERT INTO %s (%s) VALUES %s", m.table, purPurchaseOrderDetailRowsExpectAutoSet, strings.Join(placeholders, ",")) + _, err := m.conn.ExecCtx(ctx, query, args...) + return err +} + +func (m *customPurPurchaseOrderDetailModel) UpdateReceivedQty(ctx context.Context, detailId string, addQty float64) error { + query := fmt.Sprintf("UPDATE %s SET received_qty = received_qty + ? WHERE detail_id = ?", m.table) + _, err := m.conn.ExecCtx(ctx, query, addQty, detailId) + return err +} diff --git a/model/purpurchaseorderdetailmodel_gen.go b/model/purpurchaseorderdetailmodel_gen.go new file mode 100644 index 0000000..dc8f6ed --- /dev/null +++ b/model/purpurchaseorderdetailmodel_gen.go @@ -0,0 +1,100 @@ +package model + +import ( + "context" + "database/sql" + "fmt" + "strings" + + "github.com/zeromicro/go-zero/core/stores/builder" + "github.com/zeromicro/go-zero/core/stores/sqlx" + "github.com/zeromicro/go-zero/core/stringx" +) + +var ( + purPurchaseOrderDetailFieldNames = builder.RawFieldNames(&PurPurchaseOrderDetail{}) + purPurchaseOrderDetailRows = strings.Join(purPurchaseOrderDetailFieldNames, ",") + purPurchaseOrderDetailRowsExpectAutoSet = strings.Join(stringx.Remove(purPurchaseOrderDetailFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",") + purPurchaseOrderDetailRowsWithPlaceHolder = strings.Join(stringx.Remove(purPurchaseOrderDetailFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?" +) + +type ( + purPurchaseOrderDetailModel interface { + Insert(ctx context.Context, data *PurPurchaseOrderDetail) (sql.Result, error) + FindOne(ctx context.Context, id int64) (*PurPurchaseOrderDetail, error) + FindOneByDetailId(ctx context.Context, detailId string) (*PurPurchaseOrderDetail, error) + Update(ctx context.Context, data *PurPurchaseOrderDetail) error + Delete(ctx context.Context, id int64) error + } + + defaultPurPurchaseOrderDetailModel struct { + conn sqlx.SqlConn + table string + } + + PurPurchaseOrderDetail struct { + Id int64 `db:"id"` + DetailId string `db:"detail_id"` + TenantId string `db:"tenant_id"` + OrderId string `db:"order_id"` + ProductId string `db:"product_id"` + ProductName string `db:"product_name"` + Spec string `db:"spec"` + Color string `db:"color"` + Quantity float64 `db:"quantity"` + UnitPrice float64 `db:"unit_price"` + Amount float64 `db:"amount"` + ReceivedQty float64 `db:"received_qty"` + Remark sql.NullString `db:"remark"` + } +) + +func newPurPurchaseOrderDetailModel(conn sqlx.SqlConn) *defaultPurPurchaseOrderDetailModel { + return &defaultPurPurchaseOrderDetailModel{ + conn: conn, + table: "`pur_purchase_order_detail`", + } +} + +func (m *defaultPurPurchaseOrderDetailModel) Insert(ctx context.Context, data *PurPurchaseOrderDetail) (sql.Result, error) { + query := fmt.Sprintf("INSERT INTO %s (%s) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", m.table, purPurchaseOrderDetailRowsExpectAutoSet) + return m.conn.ExecCtx(ctx, query, + data.DetailId, data.TenantId, data.OrderId, data.ProductId, data.ProductName, data.Spec, + data.Color, data.Quantity, data.UnitPrice, data.Amount, data.ReceivedQty, data.Remark) +} + +func (m *defaultPurPurchaseOrderDetailModel) FindOne(ctx context.Context, id int64) (*PurPurchaseOrderDetail, error) { + query := fmt.Sprintf("SELECT %s FROM %s WHERE `id` = ? LIMIT 1", purPurchaseOrderDetailRows, m.table) + var resp PurPurchaseOrderDetail + if err := m.conn.QueryRowCtx(ctx, &resp, query, id); err != nil { + return nil, err + } + return &resp, nil +} + +func (m *defaultPurPurchaseOrderDetailModel) FindOneByDetailId(ctx context.Context, detailId string) (*PurPurchaseOrderDetail, error) { + query := fmt.Sprintf("SELECT %s FROM %s WHERE `detail_id` = ? LIMIT 1", purPurchaseOrderDetailRows, m.table) + var resp PurPurchaseOrderDetail + if err := m.conn.QueryRowCtx(ctx, &resp, query, detailId); err != nil { + return nil, err + } + return &resp, nil +} + +func (m *defaultPurPurchaseOrderDetailModel) Update(ctx context.Context, data *PurPurchaseOrderDetail) error { + query := fmt.Sprintf("UPDATE %s SET %s WHERE `id` = ?", m.table, purPurchaseOrderDetailRowsWithPlaceHolder) + _, err := m.conn.ExecCtx(ctx, query, + data.DetailId, data.TenantId, data.OrderId, data.ProductId, data.ProductName, data.Spec, + data.Color, data.Quantity, data.UnitPrice, data.Amount, data.ReceivedQty, data.Remark, data.Id) + return err +} + +func (m *defaultPurPurchaseOrderDetailModel) Delete(ctx context.Context, id int64) error { + query := fmt.Sprintf("DELETE FROM %s WHERE `id` = ?", m.table) + _, err := m.conn.ExecCtx(ctx, query, id) + return err +} + +func (m *defaultPurPurchaseOrderDetailModel) tableName() string { + return m.table +} diff --git a/model/purpurchaseordermodel.go b/model/purpurchaseordermodel.go new file mode 100644 index 0000000..bb32454 --- /dev/null +++ b/model/purpurchaseordermodel.go @@ -0,0 +1,103 @@ +package model + +import ( + "context" + "fmt" + + "github.com/zeromicro/go-zero/core/stores/cache" + "github.com/zeromicro/go-zero/core/stores/sqlx" +) + +var _ PurPurchaseOrderModel = (*customPurPurchaseOrderModel)(nil) + +type ( + PurPurchaseOrderModel interface { + purPurchaseOrderModel + FindList(ctx context.Context, tenantId string, page, pageSize int64, supplierId string, status int64, startDate, endDate string) ([]*PurPurchaseOrder, int64, error) + CountTodayOrders(ctx context.Context, tenantId, dateStr string) (int64, error) + UpdateReceiptProgress(ctx context.Context, orderId string, addQty float64) error + UpdatePaymentProgress(ctx context.Context, orderId string, addAmount float64) error + } + + customPurPurchaseOrderModel struct { + *defaultPurPurchaseOrderModel + } +) + +func NewPurPurchaseOrderModel(conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) PurPurchaseOrderModel { + return &customPurPurchaseOrderModel{ + defaultPurPurchaseOrderModel: newPurPurchaseOrderModel(conn, c, opts...), + } +} + +func (m *customPurPurchaseOrderModel) FindList(ctx context.Context, tenantId string, page, pageSize int64, supplierId string, status int64, startDate, endDate string) ([]*PurPurchaseOrder, int64, error) { + where := "WHERE tenant_id = ?" + args := []interface{}{tenantId} + + if supplierId != "" { + where += " AND supplier_id = ?" + args = append(args, supplierId) + } + if status != -1 { + where += " AND status = ?" + args = append(args, status) + } + if startDate != "" { + where += " AND order_date >= ?" + args = append(args, startDate) + } + if endDate != "" { + where += " AND order_date <= ?" + args = append(args, endDate) + } + + var total int64 + countQuery := fmt.Sprintf("SELECT COUNT(*) FROM %s %s", m.table, where) + if err := m.QueryRowNoCacheCtx(ctx, &total, countQuery, args...); err != nil { + return nil, 0, err + } + + var list []*PurPurchaseOrder + query := fmt.Sprintf("SELECT %s FROM %s %s ORDER BY created_at DESC LIMIT ? OFFSET ?", purPurchaseOrderRows, m.table, where) + args = append(args, pageSize, (page-1)*pageSize) + if err := m.QueryRowsNoCacheCtx(ctx, &list, query, args...); err != nil { + return nil, 0, err + } + return list, total, nil +} + +func (m *customPurPurchaseOrderModel) CountTodayOrders(ctx context.Context, tenantId, dateStr string) (int64, error) { + var count int64 + query := fmt.Sprintf("SELECT COUNT(*) FROM %s WHERE tenant_id = ? AND DATE(created_at) = ?", m.table) + if err := m.QueryRowNoCacheCtx(ctx, &count, query, tenantId, dateStr); err != nil { + return 0, err + } + return count, nil +} + +func (m *customPurPurchaseOrderModel) UpdateReceiptProgress(ctx context.Context, orderId string, addQty float64) error { + // Recalculate receipt_status after updating received_qty + query := fmt.Sprintf(`UPDATE %s SET + received_qty = received_qty + ?, + receipt_status = CASE + WHEN (received_qty + ?) >= (SELECT COALESCE(SUM(quantity),0) FROM pur_purchase_order_detail WHERE order_id = ?) THEN 2 + WHEN (received_qty + ?) > 0 THEN 1 + ELSE 0 + END + WHERE order_id = ?`, m.table) + _, err := m.ExecNoCacheCtx(ctx, query, addQty, addQty, orderId, addQty, orderId) + return err +} + +func (m *customPurPurchaseOrderModel) UpdatePaymentProgress(ctx context.Context, orderId string, addAmount float64) error { + query := fmt.Sprintf(`UPDATE %s SET + paid_amount = paid_amount + ?, + payment_status = CASE + WHEN (paid_amount + ?) >= contract_amount THEN 2 + WHEN (paid_amount + ?) > 0 THEN 1 + ELSE 0 + END + WHERE order_id = ?`, m.table) + _, err := m.ExecNoCacheCtx(ctx, query, addAmount, addAmount, addAmount, orderId) + return err +} diff --git a/model/purpurchaseordermodel_gen.go b/model/purpurchaseordermodel_gen.go new file mode 100644 index 0000000..77363e6 --- /dev/null +++ b/model/purpurchaseordermodel_gen.go @@ -0,0 +1,187 @@ +package model + +import ( + "context" + "database/sql" + "fmt" + "strings" + "time" + + "github.com/zeromicro/go-zero/core/stores/builder" + "github.com/zeromicro/go-zero/core/stores/cache" + "github.com/zeromicro/go-zero/core/stores/sqlc" + "github.com/zeromicro/go-zero/core/stores/sqlx" + "github.com/zeromicro/go-zero/core/stringx" +) + +var ( + purPurchaseOrderFieldNames = builder.RawFieldNames(&PurPurchaseOrder{}) + purPurchaseOrderRows = strings.Join(purPurchaseOrderFieldNames, ",") + purPurchaseOrderRowsExpectAutoSet = strings.Join(stringx.Remove(purPurchaseOrderFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",") + purPurchaseOrderRowsWithPlaceHolder = strings.Join(stringx.Remove(purPurchaseOrderFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?" + + cachePurPurchaseOrderIdPrefix = "cache:purPurchaseOrder:id:" + cachePurPurchaseOrderOrderIdPrefix = "cache:purPurchaseOrder:orderId:" + cachePurPurchaseOrderOrderNoPrefix = "cache:purPurchaseOrder:orderNo:" +) + +type ( + purPurchaseOrderModel interface { + Insert(ctx context.Context, data *PurPurchaseOrder) (sql.Result, error) + FindOne(ctx context.Context, id int64) (*PurPurchaseOrder, error) + FindOneByOrderId(ctx context.Context, orderId string) (*PurPurchaseOrder, error) + FindOneByOrderNo(ctx context.Context, orderNo string) (*PurPurchaseOrder, error) + Update(ctx context.Context, data *PurPurchaseOrder) error + Delete(ctx context.Context, id int64) error + } + + defaultPurPurchaseOrderModel struct { + sqlc.CachedConn + table string + } + + PurPurchaseOrder struct { + Id int64 `db:"id"` + OrderId string `db:"order_id"` + TenantId string `db:"tenant_id"` + OrderNo string `db:"order_no"` + SupplierId string `db:"supplier_id"` + OrderDate time.Time `db:"order_date"` + ContractAmount float64 `db:"contract_amount"` + ReceivedQty float64 `db:"received_qty"` + PaidAmount float64 `db:"paid_amount"` + PaymentStatus int64 `db:"payment_status"` + ReceiptStatus int64 `db:"receipt_status"` + PurchaseBy string `db:"purchase_by"` + Creator string `db:"creator"` + Operator string `db:"operator"` + Status int64 `db:"status"` + Remark sql.NullString `db:"remark"` + CreatedAt time.Time `db:"created_at"` + UpdatedAt time.Time `db:"updated_at"` + } +) + +func newPurPurchaseOrderModel(conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) *defaultPurPurchaseOrderModel { + return &defaultPurPurchaseOrderModel{ + CachedConn: sqlc.NewConn(conn, c, opts...), + table: "`pur_purchase_order`", + } +} + +func (m *defaultPurPurchaseOrderModel) Delete(ctx context.Context, id int64) error { + data, err := m.FindOne(ctx, id) + if err != nil { + return err + } + purPurchaseOrderIdKey := fmt.Sprintf("%s%v", cachePurPurchaseOrderIdPrefix, id) + purPurchaseOrderOrderIdKey := fmt.Sprintf("%s%v", cachePurPurchaseOrderOrderIdPrefix, data.OrderId) + purPurchaseOrderOrderNoKey := fmt.Sprintf("%s%v", cachePurPurchaseOrderOrderNoPrefix, data.OrderNo) + _, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) { + query := fmt.Sprintf("delete from %s where `id` = ?", m.table) + return conn.ExecCtx(ctx, query, id) + }, purPurchaseOrderIdKey, purPurchaseOrderOrderIdKey, purPurchaseOrderOrderNoKey) + return err +} + +func (m *defaultPurPurchaseOrderModel) FindOne(ctx context.Context, id int64) (*PurPurchaseOrder, error) { + purPurchaseOrderIdKey := fmt.Sprintf("%s%v", cachePurPurchaseOrderIdPrefix, id) + var resp PurPurchaseOrder + err := m.QueryRowCtx(ctx, &resp, purPurchaseOrderIdKey, func(ctx context.Context, conn sqlx.SqlConn, v any) error { + query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", purPurchaseOrderRows, m.table) + return conn.QueryRowCtx(ctx, v, query, id) + }) + switch err { + case nil: + return &resp, nil + case sqlc.ErrNotFound: + return nil, ErrNotFound + default: + return nil, err + } +} + +func (m *defaultPurPurchaseOrderModel) FindOneByOrderId(ctx context.Context, orderId string) (*PurPurchaseOrder, error) { + purPurchaseOrderOrderIdKey := fmt.Sprintf("%s%v", cachePurPurchaseOrderOrderIdPrefix, orderId) + var resp PurPurchaseOrder + err := m.QueryRowIndexCtx(ctx, &resp, purPurchaseOrderOrderIdKey, m.formatPrimary, func(ctx context.Context, conn sqlx.SqlConn, v any) (i any, e error) { + query := fmt.Sprintf("select %s from %s where `order_id` = ? limit 1", purPurchaseOrderRows, m.table) + if err := conn.QueryRowCtx(ctx, &resp, query, orderId); err != nil { + return nil, err + } + return resp.Id, nil + }, m.queryPrimary) + switch err { + case nil: + return &resp, nil + case sqlc.ErrNotFound: + return nil, ErrNotFound + default: + return nil, err + } +} + +func (m *defaultPurPurchaseOrderModel) FindOneByOrderNo(ctx context.Context, orderNo string) (*PurPurchaseOrder, error) { + purPurchaseOrderOrderNoKey := fmt.Sprintf("%s%v", cachePurPurchaseOrderOrderNoPrefix, orderNo) + var resp PurPurchaseOrder + err := m.QueryRowIndexCtx(ctx, &resp, purPurchaseOrderOrderNoKey, m.formatPrimary, func(ctx context.Context, conn sqlx.SqlConn, v any) (i any, e error) { + query := fmt.Sprintf("select %s from %s where `order_no` = ? limit 1", purPurchaseOrderRows, m.table) + if err := conn.QueryRowCtx(ctx, &resp, query, orderNo); err != nil { + return nil, err + } + return resp.Id, nil + }, m.queryPrimary) + switch err { + case nil: + return &resp, nil + case sqlc.ErrNotFound: + return nil, ErrNotFound + default: + return nil, err + } +} + +func (m *defaultPurPurchaseOrderModel) Insert(ctx context.Context, data *PurPurchaseOrder) (sql.Result, error) { + purPurchaseOrderIdKey := fmt.Sprintf("%s%v", cachePurPurchaseOrderIdPrefix, data.Id) + purPurchaseOrderOrderIdKey := fmt.Sprintf("%s%v", cachePurPurchaseOrderOrderIdPrefix, data.OrderId) + purPurchaseOrderOrderNoKey := fmt.Sprintf("%s%v", cachePurPurchaseOrderOrderNoPrefix, data.OrderNo) + ret, err := m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) { + query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", m.table, purPurchaseOrderRowsExpectAutoSet) + return conn.ExecCtx(ctx, query, + data.OrderId, data.TenantId, data.OrderNo, data.SupplierId, data.OrderDate, + data.ContractAmount, data.ReceivedQty, data.PaidAmount, data.PaymentStatus, data.ReceiptStatus, + data.PurchaseBy, data.Creator, data.Operator, data.Status, data.Remark) + }, purPurchaseOrderIdKey, purPurchaseOrderOrderIdKey, purPurchaseOrderOrderNoKey) + return ret, err +} + +func (m *defaultPurPurchaseOrderModel) Update(ctx context.Context, newData *PurPurchaseOrder) error { + data, err := m.FindOne(ctx, newData.Id) + if err != nil { + return err + } + purPurchaseOrderIdKey := fmt.Sprintf("%s%v", cachePurPurchaseOrderIdPrefix, data.Id) + purPurchaseOrderOrderIdKey := fmt.Sprintf("%s%v", cachePurPurchaseOrderOrderIdPrefix, data.OrderId) + purPurchaseOrderOrderNoKey := fmt.Sprintf("%s%v", cachePurPurchaseOrderOrderNoPrefix, data.OrderNo) + _, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) { + query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, purPurchaseOrderRowsWithPlaceHolder) + return conn.ExecCtx(ctx, query, + newData.OrderId, newData.TenantId, newData.OrderNo, newData.SupplierId, newData.OrderDate, + newData.ContractAmount, newData.ReceivedQty, newData.PaidAmount, newData.PaymentStatus, newData.ReceiptStatus, + newData.PurchaseBy, newData.Creator, newData.Operator, newData.Status, newData.Remark, newData.Id) + }, purPurchaseOrderIdKey, purPurchaseOrderOrderIdKey, purPurchaseOrderOrderNoKey) + return err +} + +func (m *defaultPurPurchaseOrderModel) formatPrimary(primary any) string { + return fmt.Sprintf("%s%v", cachePurPurchaseOrderIdPrefix, primary) +} + +func (m *defaultPurPurchaseOrderModel) queryPrimary(ctx context.Context, conn sqlx.SqlConn, v, primary any) error { + query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", purPurchaseOrderRows, m.table) + return conn.QueryRowCtx(ctx, v, query, primary) +} + +func (m *defaultPurPurchaseOrderModel) tableName() string { + return m.table +} diff --git a/model/purpurchasepaymentmodel.go b/model/purpurchasepaymentmodel.go new file mode 100644 index 0000000..0c7b357 --- /dev/null +++ b/model/purpurchasepaymentmodel.go @@ -0,0 +1,83 @@ +package model + +import ( + "context" + "fmt" + + "github.com/zeromicro/go-zero/core/stores/sqlx" +) + +var _ PurPurchasePaymentModel = (*customPurPurchasePaymentModel)(nil) + +type ( + PurPurchasePaymentModel interface { + purPurchasePaymentModel + FindByOrderId(ctx context.Context, orderId string) ([]*PurPurchasePayment, error) + FindList(ctx context.Context, tenantId string, page, pageSize int64, orderId, supplierId string, startDate, endDate string) ([]*PurPurchasePayment, int64, error) + CountTodayPayments(ctx context.Context, tenantId, dateStr string) (int64, error) + } + + customPurPurchasePaymentModel struct { + *defaultPurPurchasePaymentModel + } +) + +func NewPurPurchasePaymentModel(conn sqlx.SqlConn) PurPurchasePaymentModel { + return &customPurPurchasePaymentModel{ + defaultPurPurchasePaymentModel: newPurPurchasePaymentModel(conn), + } +} + +func (m *customPurPurchasePaymentModel) FindByOrderId(ctx context.Context, orderId string) ([]*PurPurchasePayment, error) { + var list []*PurPurchasePayment + query := fmt.Sprintf("SELECT %s FROM %s WHERE order_id = ? ORDER BY created_at DESC", purPurchasePaymentRows, m.table) + if err := m.conn.QueryRowsCtx(ctx, &list, query, orderId); err != nil { + return nil, err + } + return list, nil +} + +func (m *customPurPurchasePaymentModel) FindList(ctx context.Context, tenantId string, page, pageSize int64, orderId, supplierId string, startDate, endDate string) ([]*PurPurchasePayment, int64, error) { + where := "WHERE tenant_id = ?" + args := []interface{}{tenantId} + + if orderId != "" { + where += " AND order_id = ?" + args = append(args, orderId) + } + if supplierId != "" { + where += " AND supplier_id = ?" + args = append(args, supplierId) + } + if startDate != "" { + where += " AND payment_date >= ?" + args = append(args, startDate) + } + if endDate != "" { + where += " AND payment_date <= ?" + args = append(args, endDate) + } + + var total int64 + countQuery := fmt.Sprintf("SELECT COUNT(*) FROM %s %s", m.table, where) + if err := m.conn.QueryRowCtx(ctx, &total, countQuery, args...); err != nil { + return nil, 0, err + } + + var list []*PurPurchasePayment + query := fmt.Sprintf("SELECT %s FROM %s %s ORDER BY created_at DESC LIMIT ? OFFSET ?", purPurchasePaymentRows, m.table, where) + args = append(args, pageSize, (page-1)*pageSize) + if err := m.conn.QueryRowsCtx(ctx, &list, query, args...); err != nil { + return nil, 0, err + } + return list, total, nil +} + +func (m *customPurPurchasePaymentModel) CountTodayPayments(ctx context.Context, tenantId, dateStr string) (int64, error) { + var count int64 + query := fmt.Sprintf("SELECT COUNT(*) FROM %s WHERE tenant_id = ? AND DATE(created_at) = ?", m.table) + if err := m.conn.QueryRowCtx(ctx, &count, query, tenantId, dateStr); err != nil { + return 0, err + } + return count, nil +} diff --git a/model/purpurchasepaymentmodel_gen.go b/model/purpurchasepaymentmodel_gen.go new file mode 100644 index 0000000..b86c629 --- /dev/null +++ b/model/purpurchasepaymentmodel_gen.go @@ -0,0 +1,99 @@ +package model + +import ( + "context" + "database/sql" + "fmt" + "strings" + "time" + + "github.com/zeromicro/go-zero/core/stores/builder" + "github.com/zeromicro/go-zero/core/stores/sqlx" + "github.com/zeromicro/go-zero/core/stringx" +) + +var ( + purPurchasePaymentFieldNames = builder.RawFieldNames(&PurPurchasePayment{}) + purPurchasePaymentRows = strings.Join(purPurchasePaymentFieldNames, ",") + purPurchasePaymentRowsExpectAutoSet = strings.Join(stringx.Remove(purPurchasePaymentFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",") + purPurchasePaymentRowsWithPlaceHolder = strings.Join(stringx.Remove(purPurchasePaymentFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?" +) + +type ( + purPurchasePaymentModel interface { + Insert(ctx context.Context, data *PurPurchasePayment) (sql.Result, error) + FindOne(ctx context.Context, id int64) (*PurPurchasePayment, error) + FindOneByPaymentId(ctx context.Context, paymentId string) (*PurPurchasePayment, error) + Update(ctx context.Context, data *PurPurchasePayment) error + Delete(ctx context.Context, id int64) error + } + + defaultPurPurchasePaymentModel struct { + conn sqlx.SqlConn + table string + } + + PurPurchasePayment struct { + Id int64 `db:"id"` + PaymentId string `db:"payment_id"` + TenantId string `db:"tenant_id"` + OrderId string `db:"order_id"` + SupplierId string `db:"supplier_id"` + PaymentDate time.Time `db:"payment_date"` + Amount float64 `db:"amount"` + PaymentMethod string `db:"payment_method"` + Operator string `db:"operator"` + Remark sql.NullString `db:"remark"` + CreatedAt time.Time `db:"created_at"` + } +) + +func newPurPurchasePaymentModel(conn sqlx.SqlConn) *defaultPurPurchasePaymentModel { + return &defaultPurPurchasePaymentModel{ + conn: conn, + table: "`pur_purchase_payment`", + } +} + +func (m *defaultPurPurchasePaymentModel) Insert(ctx context.Context, data *PurPurchasePayment) (sql.Result, error) { + query := fmt.Sprintf("INSERT INTO %s (%s) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", m.table, purPurchasePaymentRowsExpectAutoSet) + return m.conn.ExecCtx(ctx, query, + data.PaymentId, data.TenantId, data.OrderId, data.SupplierId, data.PaymentDate, + data.Amount, data.PaymentMethod, data.Operator, data.Remark) +} + +func (m *defaultPurPurchasePaymentModel) FindOne(ctx context.Context, id int64) (*PurPurchasePayment, error) { + query := fmt.Sprintf("SELECT %s FROM %s WHERE `id` = ? LIMIT 1", purPurchasePaymentRows, m.table) + var resp PurPurchasePayment + if err := m.conn.QueryRowCtx(ctx, &resp, query, id); err != nil { + return nil, err + } + return &resp, nil +} + +func (m *defaultPurPurchasePaymentModel) FindOneByPaymentId(ctx context.Context, paymentId string) (*PurPurchasePayment, error) { + query := fmt.Sprintf("SELECT %s FROM %s WHERE `payment_id` = ? LIMIT 1", purPurchasePaymentRows, m.table) + var resp PurPurchasePayment + if err := m.conn.QueryRowCtx(ctx, &resp, query, paymentId); err != nil { + return nil, err + } + return &resp, nil +} + +func (m *defaultPurPurchasePaymentModel) Update(ctx context.Context, data *PurPurchasePayment) error { + query := fmt.Sprintf("UPDATE %s SET %s WHERE `id` = ?", m.table, purPurchasePaymentRowsWithPlaceHolder) + _, err := m.conn.ExecCtx(ctx, query, + data.PaymentId, data.TenantId, data.OrderId, data.SupplierId, data.PaymentDate, + data.Amount, data.PaymentMethod, data.Operator, data.Remark, data.Id) + return err +} + +func (m *defaultPurPurchasePaymentModel) Delete(ctx context.Context, id int64) error { + query := fmt.Sprintf("DELETE FROM %s WHERE `id` = ?", m.table) + _, err := m.conn.ExecCtx(ctx, query, id) + return err +} + +func (m *defaultPurPurchasePaymentModel) tableName() string { + return m.table +} diff --git a/model/purpurchasereceiptdetailmodel.go b/model/purpurchasereceiptdetailmodel.go new file mode 100644 index 0000000..7206126 --- /dev/null +++ b/model/purpurchasereceiptdetailmodel.go @@ -0,0 +1,61 @@ +package model + +import ( + "context" + "fmt" + "strings" + + "github.com/zeromicro/go-zero/core/stores/sqlx" +) + +var _ PurPurchaseReceiptDetailModel = (*customPurPurchaseReceiptDetailModel)(nil) + +type ( + PurPurchaseReceiptDetailModel interface { + purPurchaseReceiptDetailModel + FindByReceiptId(ctx context.Context, receiptId string) ([]*PurPurchaseReceiptDetail, error) + DeleteByReceiptId(ctx context.Context, receiptId string) error + BulkInsert(ctx context.Context, details []*PurPurchaseReceiptDetail) error + } + + customPurPurchaseReceiptDetailModel struct { + *defaultPurPurchaseReceiptDetailModel + } +) + +func NewPurPurchaseReceiptDetailModel(conn sqlx.SqlConn) PurPurchaseReceiptDetailModel { + return &customPurPurchaseReceiptDetailModel{ + defaultPurPurchaseReceiptDetailModel: newPurPurchaseReceiptDetailModel(conn), + } +} + +func (m *customPurPurchaseReceiptDetailModel) FindByReceiptId(ctx context.Context, receiptId string) ([]*PurPurchaseReceiptDetail, error) { + var list []*PurPurchaseReceiptDetail + query := fmt.Sprintf("SELECT %s FROM %s WHERE receipt_id = ?", purPurchaseReceiptDetailRows, m.table) + if err := m.conn.QueryRowsCtx(ctx, &list, query, receiptId); err != nil { + return nil, err + } + return list, nil +} + +func (m *customPurPurchaseReceiptDetailModel) DeleteByReceiptId(ctx context.Context, receiptId string) error { + query := fmt.Sprintf("DELETE FROM %s WHERE receipt_id = ?", m.table) + _, err := m.conn.ExecCtx(ctx, query, receiptId) + return err +} + +func (m *customPurPurchaseReceiptDetailModel) BulkInsert(ctx context.Context, details []*PurPurchaseReceiptDetail) error { + if len(details) == 0 { + return nil + } + placeholder := "(?, ?, ?, ?, ?, ?, ?)" + placeholders := make([]string, len(details)) + args := make([]interface{}, 0, len(details)*7) + for i, d := range details { + placeholders[i] = placeholder + args = append(args, d.DetailId, d.ReceiptId, d.OrderDetailId, d.ProductId, d.ActualQty, d.UnitCost, d.Remark) + } + query := fmt.Sprintf("INSERT INTO %s (%s) VALUES %s", m.table, purPurchaseReceiptDetailRowsExpectAutoSet, strings.Join(placeholders, ",")) + _, err := m.conn.ExecCtx(ctx, query, args...) + return err +} diff --git a/model/purpurchasereceiptdetailmodel_gen.go b/model/purpurchasereceiptdetailmodel_gen.go new file mode 100644 index 0000000..7968f17 --- /dev/null +++ b/model/purpurchasereceiptdetailmodel_gen.go @@ -0,0 +1,93 @@ +package model + +import ( + "context" + "database/sql" + "fmt" + "strings" + + "github.com/zeromicro/go-zero/core/stores/builder" + "github.com/zeromicro/go-zero/core/stores/sqlx" + "github.com/zeromicro/go-zero/core/stringx" +) + +var ( + purPurchaseReceiptDetailFieldNames = builder.RawFieldNames(&PurPurchaseReceiptDetail{}) + purPurchaseReceiptDetailRows = strings.Join(purPurchaseReceiptDetailFieldNames, ",") + purPurchaseReceiptDetailRowsExpectAutoSet = strings.Join(stringx.Remove(purPurchaseReceiptDetailFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",") + purPurchaseReceiptDetailRowsWithPlaceHolder = strings.Join(stringx.Remove(purPurchaseReceiptDetailFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?" +) + +type ( + purPurchaseReceiptDetailModel interface { + Insert(ctx context.Context, data *PurPurchaseReceiptDetail) (sql.Result, error) + FindOne(ctx context.Context, id int64) (*PurPurchaseReceiptDetail, error) + FindOneByDetailId(ctx context.Context, detailId string) (*PurPurchaseReceiptDetail, error) + Update(ctx context.Context, data *PurPurchaseReceiptDetail) error + Delete(ctx context.Context, id int64) error + } + + defaultPurPurchaseReceiptDetailModel struct { + conn sqlx.SqlConn + table string + } + + PurPurchaseReceiptDetail struct { + Id int64 `db:"id"` + DetailId string `db:"detail_id"` + ReceiptId string `db:"receipt_id"` + OrderDetailId string `db:"order_detail_id"` + ProductId string `db:"product_id"` + ActualQty float64 `db:"actual_qty"` + UnitCost float64 `db:"unit_cost"` + Remark sql.NullString `db:"remark"` + } +) + +func newPurPurchaseReceiptDetailModel(conn sqlx.SqlConn) *defaultPurPurchaseReceiptDetailModel { + return &defaultPurPurchaseReceiptDetailModel{ + conn: conn, + table: "`pur_purchase_receipt_detail`", + } +} + +func (m *defaultPurPurchaseReceiptDetailModel) Insert(ctx context.Context, data *PurPurchaseReceiptDetail) (sql.Result, error) { + query := fmt.Sprintf("INSERT INTO %s (%s) VALUES (?, ?, ?, ?, ?, ?, ?)", m.table, purPurchaseReceiptDetailRowsExpectAutoSet) + return m.conn.ExecCtx(ctx, query, + data.DetailId, data.ReceiptId, data.OrderDetailId, data.ProductId, data.ActualQty, data.UnitCost, data.Remark) +} + +func (m *defaultPurPurchaseReceiptDetailModel) FindOne(ctx context.Context, id int64) (*PurPurchaseReceiptDetail, error) { + query := fmt.Sprintf("SELECT %s FROM %s WHERE `id` = ? LIMIT 1", purPurchaseReceiptDetailRows, m.table) + var resp PurPurchaseReceiptDetail + if err := m.conn.QueryRowCtx(ctx, &resp, query, id); err != nil { + return nil, err + } + return &resp, nil +} + +func (m *defaultPurPurchaseReceiptDetailModel) FindOneByDetailId(ctx context.Context, detailId string) (*PurPurchaseReceiptDetail, error) { + query := fmt.Sprintf("SELECT %s FROM %s WHERE `detail_id` = ? LIMIT 1", purPurchaseReceiptDetailRows, m.table) + var resp PurPurchaseReceiptDetail + if err := m.conn.QueryRowCtx(ctx, &resp, query, detailId); err != nil { + return nil, err + } + return &resp, nil +} + +func (m *defaultPurPurchaseReceiptDetailModel) Update(ctx context.Context, data *PurPurchaseReceiptDetail) error { + query := fmt.Sprintf("UPDATE %s SET %s WHERE `id` = ?", m.table, purPurchaseReceiptDetailRowsWithPlaceHolder) + _, err := m.conn.ExecCtx(ctx, query, + data.DetailId, data.ReceiptId, data.OrderDetailId, data.ProductId, data.ActualQty, data.UnitCost, data.Remark, data.Id) + return err +} + +func (m *defaultPurPurchaseReceiptDetailModel) Delete(ctx context.Context, id int64) error { + query := fmt.Sprintf("DELETE FROM %s WHERE `id` = ?", m.table) + _, err := m.conn.ExecCtx(ctx, query, id) + return err +} + +func (m *defaultPurPurchaseReceiptDetailModel) tableName() string { + return m.table +} diff --git a/model/purpurchasereceiptmodel.go b/model/purpurchasereceiptmodel.go new file mode 100644 index 0000000..c19ddbc --- /dev/null +++ b/model/purpurchasereceiptmodel.go @@ -0,0 +1,83 @@ +package model + +import ( + "context" + "fmt" + + "github.com/zeromicro/go-zero/core/stores/sqlx" +) + +var _ PurPurchaseReceiptModel = (*customPurPurchaseReceiptModel)(nil) + +type ( + PurPurchaseReceiptModel interface { + purPurchaseReceiptModel + FindByOrderId(ctx context.Context, orderId string) ([]*PurPurchaseReceipt, error) + FindList(ctx context.Context, tenantId string, page, pageSize int64, orderId string, status int64, startDate, endDate string) ([]*PurPurchaseReceipt, int64, error) + CountTodayReceipts(ctx context.Context, tenantId, dateStr string) (int64, error) + } + + customPurPurchaseReceiptModel struct { + *defaultPurPurchaseReceiptModel + } +) + +func NewPurPurchaseReceiptModel(conn sqlx.SqlConn) PurPurchaseReceiptModel { + return &customPurPurchaseReceiptModel{ + defaultPurPurchaseReceiptModel: newPurPurchaseReceiptModel(conn), + } +} + +func (m *customPurPurchaseReceiptModel) FindByOrderId(ctx context.Context, orderId string) ([]*PurPurchaseReceipt, error) { + var list []*PurPurchaseReceipt + query := fmt.Sprintf("SELECT %s FROM %s WHERE order_id = ? ORDER BY created_at DESC", purPurchaseReceiptRows, m.table) + if err := m.conn.QueryRowsCtx(ctx, &list, query, orderId); err != nil { + return nil, err + } + return list, nil +} + +func (m *customPurPurchaseReceiptModel) FindList(ctx context.Context, tenantId string, page, pageSize int64, orderId string, status int64, startDate, endDate string) ([]*PurPurchaseReceipt, int64, error) { + where := "WHERE tenant_id = ?" + args := []interface{}{tenantId} + + if orderId != "" { + where += " AND order_id = ?" + args = append(args, orderId) + } + if status != -1 { + where += " AND status = ?" + args = append(args, status) + } + if startDate != "" { + where += " AND receipt_date >= ?" + args = append(args, startDate) + } + if endDate != "" { + where += " AND receipt_date <= ?" + args = append(args, endDate) + } + + var total int64 + countQuery := fmt.Sprintf("SELECT COUNT(*) FROM %s %s", m.table, where) + if err := m.conn.QueryRowCtx(ctx, &total, countQuery, args...); err != nil { + return nil, 0, err + } + + var list []*PurPurchaseReceipt + query := fmt.Sprintf("SELECT %s FROM %s %s ORDER BY created_at DESC LIMIT ? OFFSET ?", purPurchaseReceiptRows, m.table, where) + args = append(args, pageSize, (page-1)*pageSize) + if err := m.conn.QueryRowsCtx(ctx, &list, query, args...); err != nil { + return nil, 0, err + } + return list, total, nil +} + +func (m *customPurPurchaseReceiptModel) CountTodayReceipts(ctx context.Context, tenantId, dateStr string) (int64, error) { + var count int64 + query := fmt.Sprintf("SELECT COUNT(*) FROM %s WHERE tenant_id = ? AND DATE(created_at) = ?", m.table) + if err := m.conn.QueryRowCtx(ctx, &count, query, tenantId, dateStr); err != nil { + return 0, err + } + return count, nil +} diff --git a/model/purpurchasereceiptmodel_gen.go b/model/purpurchasereceiptmodel_gen.go new file mode 100644 index 0000000..a50ff96 --- /dev/null +++ b/model/purpurchasereceiptmodel_gen.go @@ -0,0 +1,96 @@ +package model + +import ( + "context" + "database/sql" + "fmt" + "strings" + "time" + + "github.com/zeromicro/go-zero/core/stores/builder" + "github.com/zeromicro/go-zero/core/stores/sqlx" + "github.com/zeromicro/go-zero/core/stringx" +) + +var ( + purPurchaseReceiptFieldNames = builder.RawFieldNames(&PurPurchaseReceipt{}) + purPurchaseReceiptRows = strings.Join(purPurchaseReceiptFieldNames, ",") + purPurchaseReceiptRowsExpectAutoSet = strings.Join(stringx.Remove(purPurchaseReceiptFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",") + purPurchaseReceiptRowsWithPlaceHolder = strings.Join(stringx.Remove(purPurchaseReceiptFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?" +) + +type ( + purPurchaseReceiptModel interface { + Insert(ctx context.Context, data *PurPurchaseReceipt) (sql.Result, error) + FindOne(ctx context.Context, id int64) (*PurPurchaseReceipt, error) + FindOneByReceiptId(ctx context.Context, receiptId string) (*PurPurchaseReceipt, error) + Update(ctx context.Context, data *PurPurchaseReceipt) error + Delete(ctx context.Context, id int64) error + } + + defaultPurPurchaseReceiptModel struct { + conn sqlx.SqlConn + table string + } + + PurPurchaseReceipt struct { + Id int64 `db:"id"` + ReceiptId string `db:"receipt_id"` + TenantId string `db:"tenant_id"` + ReceiptNo string `db:"receipt_no"` + OrderId string `db:"order_id"` + ReceiptDate time.Time `db:"receipt_date"` + ReceivedBy string `db:"received_by"` + Status int64 `db:"status"` + Remark sql.NullString `db:"remark"` + CreatedAt time.Time `db:"created_at"` + } +) + +func newPurPurchaseReceiptModel(conn sqlx.SqlConn) *defaultPurPurchaseReceiptModel { + return &defaultPurPurchaseReceiptModel{ + conn: conn, + table: "`pur_purchase_receipt`", + } +} + +func (m *defaultPurPurchaseReceiptModel) Insert(ctx context.Context, data *PurPurchaseReceipt) (sql.Result, error) { + query := fmt.Sprintf("INSERT INTO %s (%s) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", m.table, purPurchaseReceiptRowsExpectAutoSet) + return m.conn.ExecCtx(ctx, query, + data.ReceiptId, data.TenantId, data.ReceiptNo, data.OrderId, data.ReceiptDate, data.ReceivedBy, data.Status, data.Remark) +} + +func (m *defaultPurPurchaseReceiptModel) FindOne(ctx context.Context, id int64) (*PurPurchaseReceipt, error) { + query := fmt.Sprintf("SELECT %s FROM %s WHERE `id` = ? LIMIT 1", purPurchaseReceiptRows, m.table) + var resp PurPurchaseReceipt + if err := m.conn.QueryRowCtx(ctx, &resp, query, id); err != nil { + return nil, err + } + return &resp, nil +} + +func (m *defaultPurPurchaseReceiptModel) FindOneByReceiptId(ctx context.Context, receiptId string) (*PurPurchaseReceipt, error) { + query := fmt.Sprintf("SELECT %s FROM %s WHERE `receipt_id` = ? LIMIT 1", purPurchaseReceiptRows, m.table) + var resp PurPurchaseReceipt + if err := m.conn.QueryRowCtx(ctx, &resp, query, receiptId); err != nil { + return nil, err + } + return &resp, nil +} + +func (m *defaultPurPurchaseReceiptModel) Update(ctx context.Context, data *PurPurchaseReceipt) error { + query := fmt.Sprintf("UPDATE %s SET %s WHERE `id` = ?", m.table, purPurchaseReceiptRowsWithPlaceHolder) + _, err := m.conn.ExecCtx(ctx, query, + data.ReceiptId, data.TenantId, data.ReceiptNo, data.OrderId, data.ReceiptDate, data.ReceivedBy, data.Status, data.Remark, data.Id) + return err +} + +func (m *defaultPurPurchaseReceiptModel) Delete(ctx context.Context, id int64) error { + query := fmt.Sprintf("DELETE FROM %s WHERE `id` = ?", m.table) + _, err := m.conn.ExecCtx(ctx, query, id) + return err +} + +func (m *defaultPurPurchaseReceiptModel) tableName() string { + return m.table +} diff --git a/model/pursuppliermodel.go b/model/pursuppliermodel.go new file mode 100644 index 0000000..08405df --- /dev/null +++ b/model/pursuppliermodel.go @@ -0,0 +1,81 @@ +package model + +import ( + "context" + "fmt" + + "github.com/zeromicro/go-zero/core/stores/cache" + "github.com/zeromicro/go-zero/core/stores/sqlx" +) + +var _ PurSupplierModel = (*customPurSupplierModel)(nil) + +type ( + PurSupplierModel interface { + purSupplierModel + FindList(ctx context.Context, tenantId string, page, pageSize int64, supplierName string, status int64) ([]*PurSupplier, int64, error) + FindOneByNameAndTenant(ctx context.Context, tenantId, supplierName string) (*PurSupplier, error) + UpdateStats(ctx context.Context, supplierId string, purchaseCountDelta int64, payableDelta, paidDelta, deliveredDelta float64) error + } + + customPurSupplierModel struct { + *defaultPurSupplierModel + } +) + +func NewPurSupplierModel(conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) PurSupplierModel { + return &customPurSupplierModel{ + defaultPurSupplierModel: newPurSupplierModel(conn, c, opts...), + } +} + +func (m *customPurSupplierModel) FindList(ctx context.Context, tenantId string, page, pageSize int64, supplierName string, status int64) ([]*PurSupplier, int64, error) { + where := "WHERE tenant_id = ?" + args := []interface{}{tenantId} + + if supplierName != "" { + where += " AND supplier_name LIKE ?" + args = append(args, "%"+supplierName+"%") + } + if status != -1 { + where += " AND status = ?" + args = append(args, status) + } + + var total int64 + countQuery := fmt.Sprintf("SELECT COUNT(*) FROM %s %s", m.table, where) + if err := m.QueryRowNoCacheCtx(ctx, &total, countQuery, args...); err != nil { + return nil, 0, err + } + + var list []*PurSupplier + query := fmt.Sprintf("SELECT %s FROM %s %s ORDER BY created_at DESC LIMIT ? OFFSET ?", purSupplierRows, m.table, where) + args = append(args, pageSize, (page-1)*pageSize) + if err := m.QueryRowsNoCacheCtx(ctx, &list, query, args...); err != nil { + return nil, 0, err + } + return list, total, nil +} + +func (m *customPurSupplierModel) FindOneByNameAndTenant(ctx context.Context, tenantId, supplierName string) (*PurSupplier, error) { + var resp PurSupplier + query := fmt.Sprintf("SELECT %s FROM %s WHERE tenant_id = ? AND supplier_name = ? LIMIT 1", purSupplierRows, m.table) + err := m.QueryRowNoCacheCtx(ctx, &resp, query, tenantId, supplierName) + switch err { + case nil: + return &resp, nil + default: + return nil, err + } +} + +func (m *customPurSupplierModel) UpdateStats(ctx context.Context, supplierId string, purchaseCountDelta int64, payableDelta, paidDelta, deliveredDelta float64) error { + query := fmt.Sprintf(`UPDATE %s SET + purchase_count = purchase_count + ?, + payable_amount = payable_amount + ?, + paid_amount = paid_amount + ?, + delivered_qty = delivered_qty + ? + WHERE supplier_id = ?`, m.table) + _, err := m.ExecNoCacheCtx(ctx, query, purchaseCountDelta, payableDelta, paidDelta, deliveredDelta, supplierId) + return err +} diff --git a/model/pursuppliermodel_gen.go b/model/pursuppliermodel_gen.go new file mode 100644 index 0000000..25f7165 --- /dev/null +++ b/model/pursuppliermodel_gen.go @@ -0,0 +1,151 @@ +package model + +import ( + "context" + "database/sql" + "fmt" + "strings" + "time" + + "github.com/zeromicro/go-zero/core/stores/builder" + "github.com/zeromicro/go-zero/core/stores/cache" + "github.com/zeromicro/go-zero/core/stores/sqlc" + "github.com/zeromicro/go-zero/core/stores/sqlx" + "github.com/zeromicro/go-zero/core/stringx" +) + +var ( + purSupplierFieldNames = builder.RawFieldNames(&PurSupplier{}) + purSupplierRows = strings.Join(purSupplierFieldNames, ",") + purSupplierRowsExpectAutoSet = strings.Join(stringx.Remove(purSupplierFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",") + purSupplierRowsWithPlaceHolder = strings.Join(stringx.Remove(purSupplierFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?" + + cachePurSupplierIdPrefix = "cache:purSupplier:id:" + cachePurSupplierSupplierIdPrefix = "cache:purSupplier:supplierId:" +) + +type ( + purSupplierModel interface { + Insert(ctx context.Context, data *PurSupplier) (sql.Result, error) + FindOne(ctx context.Context, id int64) (*PurSupplier, error) + FindOneBySupplierId(ctx context.Context, supplierId string) (*PurSupplier, error) + Update(ctx context.Context, data *PurSupplier) error + Delete(ctx context.Context, id int64) error + } + + defaultPurSupplierModel struct { + sqlc.CachedConn + table string + } + + PurSupplier struct { + Id int64 `db:"id"` + SupplierId string `db:"supplier_id"` + TenantId string `db:"tenant_id"` + SupplierName string `db:"supplier_name"` + Phone string `db:"phone"` + PurchaseCount int64 `db:"purchase_count"` + DeliveredQty float64 `db:"delivered_qty"` + PayableAmount float64 `db:"payable_amount"` + PaidAmount float64 `db:"paid_amount"` + Status int64 `db:"status"` + Remark sql.NullString `db:"remark"` + CreatedAt time.Time `db:"created_at"` + UpdatedAt time.Time `db:"updated_at"` + } +) + +func newPurSupplierModel(conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) *defaultPurSupplierModel { + return &defaultPurSupplierModel{ + CachedConn: sqlc.NewConn(conn, c, opts...), + table: "`pur_supplier`", + } +} + +func (m *defaultPurSupplierModel) Delete(ctx context.Context, id int64) error { + data, err := m.FindOne(ctx, id) + if err != nil { + return err + } + purSupplierIdKey := fmt.Sprintf("%s%v", cachePurSupplierIdPrefix, id) + purSupplierSupplierIdKey := fmt.Sprintf("%s%v", cachePurSupplierSupplierIdPrefix, data.SupplierId) + _, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) { + query := fmt.Sprintf("delete from %s where `id` = ?", m.table) + return conn.ExecCtx(ctx, query, id) + }, purSupplierIdKey, purSupplierSupplierIdKey) + return err +} + +func (m *defaultPurSupplierModel) FindOne(ctx context.Context, id int64) (*PurSupplier, error) { + purSupplierIdKey := fmt.Sprintf("%s%v", cachePurSupplierIdPrefix, id) + var resp PurSupplier + err := m.QueryRowCtx(ctx, &resp, purSupplierIdKey, func(ctx context.Context, conn sqlx.SqlConn, v any) error { + query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", purSupplierRows, m.table) + return conn.QueryRowCtx(ctx, v, query, id) + }) + switch err { + case nil: + return &resp, nil + case sqlc.ErrNotFound: + return nil, ErrNotFound + default: + return nil, err + } +} + +func (m *defaultPurSupplierModel) FindOneBySupplierId(ctx context.Context, supplierId string) (*PurSupplier, error) { + purSupplierSupplierIdKey := fmt.Sprintf("%s%v", cachePurSupplierSupplierIdPrefix, supplierId) + var resp PurSupplier + err := m.QueryRowIndexCtx(ctx, &resp, purSupplierSupplierIdKey, m.formatPrimary, func(ctx context.Context, conn sqlx.SqlConn, v any) (i any, e error) { + query := fmt.Sprintf("select %s from %s where `supplier_id` = ? limit 1", purSupplierRows, m.table) + if err := conn.QueryRowCtx(ctx, &resp, query, supplierId); err != nil { + return nil, err + } + return resp.Id, nil + }, m.queryPrimary) + switch err { + case nil: + return &resp, nil + case sqlc.ErrNotFound: + return nil, ErrNotFound + default: + return nil, err + } +} + +func (m *defaultPurSupplierModel) Insert(ctx context.Context, data *PurSupplier) (sql.Result, error) { + purSupplierIdKey := fmt.Sprintf("%s%v", cachePurSupplierIdPrefix, data.Id) + purSupplierSupplierIdKey := fmt.Sprintf("%s%v", cachePurSupplierSupplierIdPrefix, data.SupplierId) + ret, err := m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) { + query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", m.table, purSupplierRowsExpectAutoSet) + return conn.ExecCtx(ctx, query, data.SupplierId, data.TenantId, data.SupplierName, data.Phone, data.PurchaseCount, data.DeliveredQty, data.PayableAmount, data.PaidAmount, data.Status, data.Remark) + }, purSupplierIdKey, purSupplierSupplierIdKey) + return ret, err +} + +func (m *defaultPurSupplierModel) Update(ctx context.Context, newData *PurSupplier) error { + data, err := m.FindOne(ctx, newData.Id) + if err != nil { + return err + } + purSupplierIdKey := fmt.Sprintf("%s%v", cachePurSupplierIdPrefix, data.Id) + purSupplierSupplierIdKey := fmt.Sprintf("%s%v", cachePurSupplierSupplierIdPrefix, data.SupplierId) + _, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) { + query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, purSupplierRowsWithPlaceHolder) + return conn.ExecCtx(ctx, query, newData.SupplierId, newData.TenantId, newData.SupplierName, newData.Phone, newData.PurchaseCount, newData.DeliveredQty, newData.PayableAmount, newData.PaidAmount, newData.Status, newData.Remark, newData.Id) + }, purSupplierIdKey, purSupplierSupplierIdKey) + return err +} + +func (m *defaultPurSupplierModel) formatPrimary(primary any) string { + return fmt.Sprintf("%s%v", cachePurSupplierIdPrefix, primary) +} + +func (m *defaultPurSupplierModel) queryPrimary(ctx context.Context, conn sqlx.SqlConn, v, primary any) error { + query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", purSupplierRows, m.table) + return conn.QueryRowCtx(ctx, v, query, primary) +} + +func (m *defaultPurSupplierModel) tableName() string { + return m.table +} diff --git a/rpc/purchase/etc/purchase.yaml b/rpc/purchase/etc/purchase.yaml new file mode 100644 index 0000000..0fbdf34 --- /dev/null +++ b/rpc/purchase/etc/purchase.yaml @@ -0,0 +1,19 @@ +Name: purchase.rpc +ListenOn: 0.0.0.0:9003 + +Etcd: + Hosts: + - 127.0.0.1:2379 + Key: purchase.rpc + +DataSource: root:muyu2026@tcp(127.0.0.1:3306)/muyu_wms?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai + +Cache: + - Host: 127.0.0.1:6379 + +PrometheusAddr: :9094 + +Log: + ServiceName: purchase-rpc + Mode: console + Level: info diff --git a/rpc/purchase/internal/config/config.go b/rpc/purchase/internal/config/config.go new file mode 100644 index 0000000..b8bbc95 --- /dev/null +++ b/rpc/purchase/internal/config/config.go @@ -0,0 +1,13 @@ +package config + +import ( + "github.com/zeromicro/go-zero/core/stores/cache" + "github.com/zeromicro/go-zero/zrpc" +) + +type Config struct { + zrpc.RpcServerConf + DataSource string + Cache cache.CacheConf + PrometheusAddr string `json:",default=:9094"` +} diff --git a/rpc/purchase/internal/logic/cancelpurchaseorderlogic.go b/rpc/purchase/internal/logic/cancelpurchaseorderlogic.go new file mode 100644 index 0000000..c282665 --- /dev/null +++ b/rpc/purchase/internal/logic/cancelpurchaseorderlogic.go @@ -0,0 +1,44 @@ +package logic + +import ( + "context" + + "muyu-apiserver/rpc/purchase/internal/svc" + "muyu-apiserver/rpc/purchase/pb" + + "github.com/zeromicro/go-zero/core/logx" +) + +type CancelPurchaseOrderLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewCancelPurchaseOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CancelPurchaseOrderLogic { + return &CancelPurchaseOrderLogic{ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx)} +} + +func (l *CancelPurchaseOrderLogic) CancelPurchaseOrder(in *pb.CancelPurchaseOrderReq) (*pb.Empty, error) { + order, err := l.svcCtx.OrderModel.FindOneByOrderId(l.ctx, in.OrderId) + if err != nil { + return nil, ErrOrderNotFound + } + // Only confirmed (status=1) with no receipt can be cancelled + if order.Status != 1 { + return nil, ErrOrderNotConfirmed + } + if order.ReceiptStatus != 0 { + return nil, ErrOrderAlreadyReceived + } + + order.Status = 2 // cancelled + if err := l.svcCtx.OrderModel.Update(l.ctx, order); err != nil { + return nil, err + } + // Reverse supplier payable + if err := l.svcCtx.SupplierModel.UpdateStats(l.ctx, order.SupplierId, -1, -order.ContractAmount, 0, 0); err != nil { + l.Errorf("reverse supplier stats failed: %v", err) + } + return &pb.Empty{}, nil +} diff --git a/rpc/purchase/internal/logic/confirmpurchaseorderlogic.go b/rpc/purchase/internal/logic/confirmpurchaseorderlogic.go new file mode 100644 index 0000000..77ff6e5 --- /dev/null +++ b/rpc/purchase/internal/logic/confirmpurchaseorderlogic.go @@ -0,0 +1,42 @@ +package logic + +import ( + "context" + + "muyu-apiserver/rpc/purchase/internal/svc" + "muyu-apiserver/rpc/purchase/pb" + + "github.com/zeromicro/go-zero/core/logx" +) + +type ConfirmPurchaseOrderLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewConfirmPurchaseOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ConfirmPurchaseOrderLogic { + return &ConfirmPurchaseOrderLogic{ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx)} +} + +func (l *ConfirmPurchaseOrderLogic) ConfirmPurchaseOrder(in *pb.ConfirmPurchaseOrderReq) (*pb.Empty, error) { + order, err := l.svcCtx.OrderModel.FindOneByOrderId(l.ctx, in.OrderId) + if err != nil { + return nil, ErrOrderNotFound + } + if order.Status != 0 { + return nil, ErrOrderNotDraft + } + + order.Status = 1 // confirmed + if err := l.svcCtx.OrderModel.Update(l.ctx, order); err != nil { + return nil, err + } + + // Update supplier stats: purchase_count++, payable_amount += contract_amount + if err := l.svcCtx.SupplierModel.UpdateStats(l.ctx, order.SupplierId, 1, order.ContractAmount, 0, 0); err != nil { + l.Errorf("update supplier stats failed: %v", err) + } + + return &pb.Empty{}, nil +} diff --git a/rpc/purchase/internal/logic/confirmpurchasereceiptlogic.go b/rpc/purchase/internal/logic/confirmpurchasereceiptlogic.go new file mode 100644 index 0000000..8693974 --- /dev/null +++ b/rpc/purchase/internal/logic/confirmpurchasereceiptlogic.go @@ -0,0 +1,90 @@ +package logic + +import ( + "context" + "database/sql" + "time" + + "muyu-apiserver/model" + "muyu-apiserver/pkg/tenantctx" + "muyu-apiserver/pkg/uid" + "muyu-apiserver/rpc/purchase/internal/svc" + "muyu-apiserver/rpc/purchase/pb" + + "github.com/zeromicro/go-zero/core/logx" +) + +type ConfirmPurchaseReceiptLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewConfirmPurchaseReceiptLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ConfirmPurchaseReceiptLogic { + return &ConfirmPurchaseReceiptLogic{ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx)} +} + +func (l *ConfirmPurchaseReceiptLogic) ConfirmPurchaseReceipt(in *pb.ConfirmPurchaseReceiptReq) (*pb.Empty, error) { + tenantId := tenantctx.ExtractTenantId(l.ctx) + + receipt, err := l.svcCtx.ReceiptModel.FindOneByReceiptId(l.ctx, in.ReceiptId) + if err != nil { + return nil, ErrReceiptNotFound + } + if receipt.Status == 1 { + return nil, ErrReceiptAlreadyConfirmed + } + + receipt.Status = 1 + if err := l.svcCtx.ReceiptModel.Update(l.ctx, receipt); err != nil { + return nil, err + } + + // Load receipt details and update order detail received_qty + write inventory logs + details, err := l.svcCtx.ReceiptDetailModel.FindByReceiptId(l.ctx, in.ReceiptId) + if err != nil { + return nil, err + } + + var totalQty float64 + for _, d := range details { + totalQty += d.ActualQty + + // Update order detail received_qty + if err := l.svcCtx.OrderDetailModel.UpdateReceivedQty(l.ctx, d.OrderDetailId, d.ActualQty); err != nil { + l.Errorf("update order detail received_qty failed: %v", err) + } + + // Write InventoryLog + _, err = l.svcCtx.InventoryLogModel.Insert(l.ctx, &model.InvInventoryLog{ + LogId: uid.Generate(), + TenantId: tenantId, + ProductId: d.ProductId, + ChangeQty: d.ActualQty, + ChangeType: 1, // purchase receipt + RefType: "PURCHASE", + RefId: in.ReceiptId, + ContactId: receipt.OrderId, + LogDate: time.Now(), + Operator: tenantId, + Remark: sql.NullString{String: receipt.ReceiptNo, Valid: true}, + }) + if err != nil { + l.Errorf("write inventory log failed: %v", err) + } + } + + // Update order received_qty and receipt_status + if err := l.svcCtx.OrderModel.UpdateReceiptProgress(l.ctx, receipt.OrderId, totalQty); err != nil { + l.Errorf("update order receipt progress failed: %v", err) + } + + // Update supplier delivered_qty + if order, err := l.svcCtx.OrderModel.FindOneByOrderId(l.ctx, receipt.OrderId); err == nil { + if err := l.svcCtx.SupplierModel.UpdateStats(l.ctx, order.SupplierId, 0, 0, 0, totalQty); err != nil { + l.Errorf("update supplier delivered_qty failed: %v", err) + } + } + + return &pb.Empty{}, nil +} diff --git a/rpc/purchase/internal/logic/createpurchaseorderlogic.go b/rpc/purchase/internal/logic/createpurchaseorderlogic.go new file mode 100644 index 0000000..3923af7 --- /dev/null +++ b/rpc/purchase/internal/logic/createpurchaseorderlogic.go @@ -0,0 +1,95 @@ +package logic + +import ( + "context" + "database/sql" + "fmt" + "strconv" + "time" + + "muyu-apiserver/model" + "muyu-apiserver/pkg/tenantctx" + "muyu-apiserver/pkg/uid" + "muyu-apiserver/rpc/purchase/internal/svc" + "muyu-apiserver/rpc/purchase/pb" + + "github.com/zeromicro/go-zero/core/logx" +) + +type CreatePurchaseOrderLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewCreatePurchaseOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreatePurchaseOrderLogic { + return &CreatePurchaseOrderLogic{ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx)} +} + +func (l *CreatePurchaseOrderLogic) CreatePurchaseOrder(in *pb.CreatePurchaseOrderReq) (*pb.IdResp, error) { + tenantId := tenantctx.ExtractTenantId(l.ctx) + + // Generate order number PO-YYYYMMDD-XXXX + today := time.Now().Format("20060102") + count, err := l.svcCtx.OrderModel.CountTodayOrders(l.ctx, tenantId, time.Now().Format("2006-01-02")) + if err != nil { + return nil, err + } + orderNo := fmt.Sprintf("PO-%s-%04d", today, count+1) + + orderDate, err := time.Parse("2006-01-02", in.OrderDate) + if err != nil { + orderDate = time.Now() + } + + // Calculate contract amount from details + var contractAmount float64 + for _, d := range in.Details { + qty, _ := strconv.ParseFloat(d.Quantity, 64) + price, _ := strconv.ParseFloat(d.UnitPrice, 64) + contractAmount += qty * price + } + + orderId := uid.Generate() + _, err = l.svcCtx.OrderModel.Insert(l.ctx, &model.PurPurchaseOrder{ + OrderId: orderId, + TenantId: tenantId, + OrderNo: orderNo, + SupplierId: in.SupplierId, + OrderDate: orderDate, + ContractAmount: contractAmount, + PurchaseBy: in.PurchaseBy, + Creator: tenantId, + Operator: tenantId, + Status: 0, // draft + Remark: sql.NullString{String: in.Remark, Valid: in.Remark != ""}, + }) + if err != nil { + return nil, err + } + + // Create details + details := make([]*model.PurPurchaseOrderDetail, 0, len(in.Details)) + for _, d := range in.Details { + qty, _ := strconv.ParseFloat(d.Quantity, 64) + price, _ := strconv.ParseFloat(d.UnitPrice, 64) + details = append(details, &model.PurPurchaseOrderDetail{ + DetailId: uid.Generate(), + TenantId: tenantId, + OrderId: orderId, + ProductId: d.ProductId, + ProductName: d.ProductName, + Spec: d.Spec, + Color: d.Color, + Quantity: qty, + UnitPrice: price, + Amount: qty * price, + Remark: sql.NullString{String: d.Remark, Valid: d.Remark != ""}, + }) + } + if err := l.svcCtx.OrderDetailModel.BulkInsert(l.ctx, details); err != nil { + return nil, err + } + + return &pb.IdResp{Id: orderId}, nil +} diff --git a/rpc/purchase/internal/logic/createpurchasepaymentlogic.go b/rpc/purchase/internal/logic/createpurchasepaymentlogic.go new file mode 100644 index 0000000..5a57f64 --- /dev/null +++ b/rpc/purchase/internal/logic/createpurchasepaymentlogic.go @@ -0,0 +1,78 @@ +package logic + +import ( + "context" + "database/sql" + "fmt" + "strconv" + "time" + + "muyu-apiserver/model" + "muyu-apiserver/pkg/tenantctx" + "muyu-apiserver/pkg/uid" + "muyu-apiserver/rpc/purchase/internal/svc" + "muyu-apiserver/rpc/purchase/pb" + + "github.com/zeromicro/go-zero/core/logx" +) + +type CreatePurchasePaymentLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewCreatePurchasePaymentLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreatePurchasePaymentLogic { + return &CreatePurchasePaymentLogic{ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx)} +} + +func (l *CreatePurchasePaymentLogic) CreatePurchasePayment(in *pb.CreatePurchasePaymentReq) (*pb.IdResp, error) { + tenantId := tenantctx.ExtractTenantId(l.ctx) + + order, err := l.svcCtx.OrderModel.FindOneByOrderId(l.ctx, in.OrderId) + if err != nil { + return nil, ErrOrderNotFound + } + + amount, _ := strconv.ParseFloat(in.Amount, 64) + + paymentDate, err := time.Parse("2006-01-02", in.PaymentDate) + if err != nil { + paymentDate = time.Now() + } + + // Generate payment number + today := time.Now().Format("20060102") + count, err := l.svcCtx.PaymentModel.CountTodayPayments(l.ctx, tenantId, time.Now().Format("2006-01-02")) + if err != nil { + count = 0 + } + _ = fmt.Sprintf("PAY-%s-%04d", today, count+1) + + paymentId := uid.Generate() + _, err = l.svcCtx.PaymentModel.Insert(l.ctx, &model.PurPurchasePayment{ + PaymentId: paymentId, + TenantId: tenantId, + OrderId: in.OrderId, + SupplierId: order.SupplierId, + PaymentDate: paymentDate, + Amount: amount, + PaymentMethod: in.PaymentMethod, + Operator: tenantId, + Remark: sql.NullString{String: in.Remark, Valid: in.Remark != ""}, + }) + if err != nil { + return nil, err + } + + // Update order paid_amount and payment_status + if err := l.svcCtx.OrderModel.UpdatePaymentProgress(l.ctx, in.OrderId, amount); err != nil { + l.Errorf("update order payment progress failed: %v", err) + } + // Update supplier paid_amount + if err := l.svcCtx.SupplierModel.UpdateStats(l.ctx, order.SupplierId, 0, 0, amount, 0); err != nil { + l.Errorf("update supplier paid_amount failed: %v", err) + } + + return &pb.IdResp{Id: paymentId}, nil +} diff --git a/rpc/purchase/internal/logic/createpurchasereceiptlogic.go b/rpc/purchase/internal/logic/createpurchasereceiptlogic.go new file mode 100644 index 0000000..fdd1c6c --- /dev/null +++ b/rpc/purchase/internal/logic/createpurchasereceiptlogic.go @@ -0,0 +1,87 @@ +package logic + +import ( + "context" + "database/sql" + "fmt" + "strconv" + "time" + + "muyu-apiserver/model" + "muyu-apiserver/pkg/tenantctx" + "muyu-apiserver/pkg/uid" + "muyu-apiserver/rpc/purchase/internal/svc" + "muyu-apiserver/rpc/purchase/pb" + + "github.com/zeromicro/go-zero/core/logx" +) + +type CreatePurchaseReceiptLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewCreatePurchaseReceiptLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreatePurchaseReceiptLogic { + return &CreatePurchaseReceiptLogic{ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx)} +} + +func (l *CreatePurchaseReceiptLogic) CreatePurchaseReceipt(in *pb.CreatePurchaseReceiptReq) (*pb.IdResp, error) { + tenantId := tenantctx.ExtractTenantId(l.ctx) + + order, err := l.svcCtx.OrderModel.FindOneByOrderId(l.ctx, in.OrderId) + if err != nil { + return nil, ErrOrderNotFound + } + if order.Status != 1 { + return nil, ErrOrderNotConfirmed + } + + // Generate receipt number + today := time.Now().Format("20060102") + count, err := l.svcCtx.ReceiptModel.CountTodayReceipts(l.ctx, tenantId, time.Now().Format("2006-01-02")) + if err != nil { + return nil, err + } + receiptNo := fmt.Sprintf("REC-%s-%04d", today, count+1) + + receiptDate, err := time.Parse("2006-01-02", in.ReceiptDate) + if err != nil { + receiptDate = time.Now() + } + + receiptId := uid.Generate() + _, err = l.svcCtx.ReceiptModel.Insert(l.ctx, &model.PurPurchaseReceipt{ + ReceiptId: receiptId, + TenantId: tenantId, + ReceiptNo: receiptNo, + OrderId: in.OrderId, + ReceiptDate: receiptDate, + ReceivedBy: in.ReceivedBy, + Status: 0, // draft + Remark: sql.NullString{String: in.Remark, Valid: in.Remark != ""}, + }) + if err != nil { + return nil, err + } + + details := make([]*model.PurPurchaseReceiptDetail, 0, len(in.Details)) + for _, d := range in.Details { + qty, _ := strconv.ParseFloat(d.ActualQty, 64) + cost, _ := strconv.ParseFloat(d.UnitCost, 64) + details = append(details, &model.PurPurchaseReceiptDetail{ + DetailId: uid.Generate(), + ReceiptId: receiptId, + OrderDetailId: d.OrderDetailId, + ProductId: d.ProductId, + ActualQty: qty, + UnitCost: cost, + Remark: sql.NullString{String: d.Remark, Valid: d.Remark != ""}, + }) + } + if err := l.svcCtx.ReceiptDetailModel.BulkInsert(l.ctx, details); err != nil { + return nil, err + } + + return &pb.IdResp{Id: receiptId}, nil +} diff --git a/rpc/purchase/internal/logic/createsupplierlogic.go b/rpc/purchase/internal/logic/createsupplierlogic.go new file mode 100644 index 0000000..a7f0490 --- /dev/null +++ b/rpc/purchase/internal/logic/createsupplierlogic.go @@ -0,0 +1,47 @@ +package logic + +import ( + "context" + "database/sql" + + "muyu-apiserver/model" + "muyu-apiserver/pkg/tenantctx" + "muyu-apiserver/pkg/uid" + "muyu-apiserver/rpc/purchase/internal/svc" + "muyu-apiserver/rpc/purchase/pb" + + "github.com/zeromicro/go-zero/core/logx" +) + +type CreateSupplierLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewCreateSupplierLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateSupplierLogic { + return &CreateSupplierLogic{ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx)} +} + +func (l *CreateSupplierLogic) CreateSupplier(in *pb.CreateSupplierReq) (*pb.IdResp, error) { + tenantId := tenantctx.ExtractTenantId(l.ctx) + + existing, err := l.svcCtx.SupplierModel.FindOneByNameAndTenant(l.ctx, tenantId, in.SupplierName) + if err == nil && existing != nil { + return nil, ErrSupplierNameExists + } + + supplierId := uid.Generate() + _, err = l.svcCtx.SupplierModel.Insert(l.ctx, &model.PurSupplier{ + SupplierId: supplierId, + TenantId: tenantId, + SupplierName: in.SupplierName, + Phone: in.Phone, + Status: 1, + Remark: sql.NullString{String: in.Remark, Valid: in.Remark != ""}, + }) + if err != nil { + return nil, err + } + return &pb.IdResp{Id: supplierId}, nil +} diff --git a/rpc/purchase/internal/logic/deletesupplierlogic.go b/rpc/purchase/internal/logic/deletesupplierlogic.go new file mode 100644 index 0000000..3bf7b45 --- /dev/null +++ b/rpc/purchase/internal/logic/deletesupplierlogic.go @@ -0,0 +1,31 @@ +package logic + +import ( + "context" + + "muyu-apiserver/rpc/purchase/internal/svc" + "muyu-apiserver/rpc/purchase/pb" + + "github.com/zeromicro/go-zero/core/logx" +) + +type DeleteSupplierLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewDeleteSupplierLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DeleteSupplierLogic { + return &DeleteSupplierLogic{ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx)} +} + +func (l *DeleteSupplierLogic) DeleteSupplier(in *pb.DeleteSupplierReq) (*pb.Empty, error) { + s, err := l.svcCtx.SupplierModel.FindOneBySupplierId(l.ctx, in.SupplierId) + if err != nil { + return nil, ErrSupplierNotFound + } + if err := l.svcCtx.SupplierModel.Delete(l.ctx, s.Id); err != nil { + return nil, err + } + return &pb.Empty{}, nil +} diff --git a/rpc/purchase/internal/logic/errors.go b/rpc/purchase/internal/logic/errors.go new file mode 100644 index 0000000..22e0554 --- /dev/null +++ b/rpc/purchase/internal/logic/errors.go @@ -0,0 +1,15 @@ +package logic + +import "errors" + +var ( + ErrSupplierNameExists = errors.New("supplier name already exists") + ErrSupplierNotFound = errors.New("supplier not found") + ErrOrderNotFound = errors.New("purchase order not found") + ErrOrderNotDraft = errors.New("order must be in draft status") + ErrOrderNotConfirmed = errors.New("order must be confirmed to create receipt") + ErrOrderAlreadyReceived = errors.New("order already fully received") + ErrReceiptNotFound = errors.New("purchase receipt not found") + ErrReceiptAlreadyConfirmed = errors.New("receipt already confirmed") + ErrPaymentNotFound = errors.New("payment record not found") +) diff --git a/rpc/purchase/internal/logic/getpurchaseorderlogic.go b/rpc/purchase/internal/logic/getpurchaseorderlogic.go new file mode 100644 index 0000000..0d942b4 --- /dev/null +++ b/rpc/purchase/internal/logic/getpurchaseorderlogic.go @@ -0,0 +1,77 @@ +package logic + +import ( + "context" + "fmt" + + "muyu-apiserver/rpc/purchase/internal/svc" + "muyu-apiserver/rpc/purchase/pb" + + "github.com/zeromicro/go-zero/core/logx" +) + +type GetPurchaseOrderLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewGetPurchaseOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetPurchaseOrderLogic { + return &GetPurchaseOrderLogic{ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx)} +} + +func (l *GetPurchaseOrderLogic) GetPurchaseOrder(in *pb.GetPurchaseOrderReq) (*pb.PurchaseOrderInfo, error) { + order, err := l.svcCtx.OrderModel.FindOneByOrderId(l.ctx, in.OrderId) + if err != nil { + return nil, ErrOrderNotFound + } + + details, err := l.svcCtx.OrderDetailModel.FindByOrderId(l.ctx, in.OrderId) + if err != nil { + return nil, err + } + + pbDetails := make([]*pb.PurchaseOrderDetailInfo, 0, len(details)) + for _, d := range details { + pbDetails = append(pbDetails, &pb.PurchaseOrderDetailInfo{ + DetailId: d.DetailId, + OrderId: d.OrderId, + ProductId: d.ProductId, + ProductName: d.ProductName, + Spec: d.Spec, + Color: d.Color, + Quantity: fmt.Sprintf("%.2f", d.Quantity), + UnitPrice: fmt.Sprintf("%.2f", d.UnitPrice), + Amount: fmt.Sprintf("%.2f", d.Amount), + ReceivedQty: fmt.Sprintf("%.2f", d.ReceivedQty), + Remark: d.Remark.String, + }) + } + + // Get supplier name + supplierName := "" + if s, err := l.svcCtx.SupplierModel.FindOneBySupplierId(l.ctx, order.SupplierId); err == nil { + supplierName = s.SupplierName + } + + return &pb.PurchaseOrderInfo{ + OrderId: order.OrderId, + OrderNo: order.OrderNo, + SupplierId: order.SupplierId, + SupplierName: supplierName, + OrderDate: order.OrderDate.Format("2006-01-02"), + ContractAmount: fmt.Sprintf("%.2f", order.ContractAmount), + ReceivedQty: fmt.Sprintf("%.2f", order.ReceivedQty), + PaidAmount: fmt.Sprintf("%.2f", order.PaidAmount), + PaymentStatus: order.PaymentStatus, + ReceiptStatus: order.ReceiptStatus, + PurchaseBy: order.PurchaseBy, + Creator: order.Creator, + Operator: order.Operator, + Status: order.Status, + Remark: order.Remark.String, + CreatedAt: order.CreatedAt.Format("2006-01-02 15:04:05"), + UpdatedAt: order.UpdatedAt.Format("2006-01-02 15:04:05"), + Details: pbDetails, + }, nil +} diff --git a/rpc/purchase/internal/logic/getpurchasereceiptlogic.go b/rpc/purchase/internal/logic/getpurchasereceiptlogic.go new file mode 100644 index 0000000..113c8fd --- /dev/null +++ b/rpc/purchase/internal/logic/getpurchasereceiptlogic.go @@ -0,0 +1,58 @@ +package logic + +import ( + "context" + "fmt" + + "muyu-apiserver/rpc/purchase/internal/svc" + "muyu-apiserver/rpc/purchase/pb" + + "github.com/zeromicro/go-zero/core/logx" +) + +type GetPurchaseReceiptLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewGetPurchaseReceiptLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetPurchaseReceiptLogic { + return &GetPurchaseReceiptLogic{ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx)} +} + +func (l *GetPurchaseReceiptLogic) GetPurchaseReceipt(in *pb.GetPurchaseReceiptReq) (*pb.PurchaseReceiptInfo, error) { + receipt, err := l.svcCtx.ReceiptModel.FindOneByReceiptId(l.ctx, in.ReceiptId) + if err != nil { + return nil, ErrReceiptNotFound + } + + details, err := l.svcCtx.ReceiptDetailModel.FindByReceiptId(l.ctx, in.ReceiptId) + if err != nil { + return nil, err + } + + pbDetails := make([]*pb.PurchaseReceiptDetailInfo, 0, len(details)) + for _, d := range details { + pbDetails = append(pbDetails, &pb.PurchaseReceiptDetailInfo{ + DetailId: d.DetailId, + ReceiptId: d.ReceiptId, + OrderDetailId: d.OrderDetailId, + ProductId: d.ProductId, + ActualQty: fmt.Sprintf("%.2f", d.ActualQty), + UnitCost: fmt.Sprintf("%.2f", d.UnitCost), + Remark: d.Remark.String, + }) + } + + return &pb.PurchaseReceiptInfo{ + ReceiptId: receipt.ReceiptId, + ReceiptNo: receipt.ReceiptNo, + OrderId: receipt.OrderId, + ReceiptDate: receipt.ReceiptDate.Format("2006-01-02"), + ReceivedBy: receipt.ReceivedBy, + Status: receipt.Status, + Remark: receipt.Remark.String, + CreatedAt: receipt.CreatedAt.Format("2006-01-02 15:04:05"), + Details: pbDetails, + }, nil +} diff --git a/rpc/purchase/internal/logic/getpurchasestatsbyproductlogic.go b/rpc/purchase/internal/logic/getpurchasestatsbyproductlogic.go new file mode 100644 index 0000000..1eed34b --- /dev/null +++ b/rpc/purchase/internal/logic/getpurchasestatsbyproductlogic.go @@ -0,0 +1,86 @@ +package logic + +import ( + "context" + "fmt" + + "muyu-apiserver/pkg/tenantctx" + "muyu-apiserver/rpc/purchase/internal/svc" + "muyu-apiserver/rpc/purchase/pb" + + "github.com/zeromicro/go-zero/core/logx" +) + +type GetPurchaseStatsByProductLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewGetPurchaseStatsByProductLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetPurchaseStatsByProductLogic { + return &GetPurchaseStatsByProductLogic{ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx)} +} + +func (l *GetPurchaseStatsByProductLogic) GetPurchaseStatsByProduct(in *pb.PurchaseStatsSummaryReq) (*pb.PurchaseStatsByProductResp, error) { + tenantId := tenantctx.ExtractTenantId(l.ctx) + + orders, _, err := l.svcCtx.OrderModel.FindList(l.ctx, tenantId, 1, 10000, "", -1, in.StartDate, in.EndDate) + if err != nil { + return nil, err + } + + type productKey struct { + productId string + } + type productStats struct { + productName string + spec string + color string + totalQty float64 + totalAmount float64 + orderCount int64 + } + statsMap := map[string]*productStats{} + + for _, o := range orders { + if o.Status == 2 { + continue + } + details, err := l.svcCtx.OrderDetailModel.FindByOrderId(l.ctx, o.OrderId) + if err != nil { + continue + } + for _, d := range details { + s := statsMap[d.ProductId] + if s == nil { + s = &productStats{ + productName: d.ProductName, + spec: d.Spec, + color: d.Color, + } + statsMap[d.ProductId] = s + } + s.totalQty += d.Quantity + s.totalAmount += d.Amount + s.orderCount++ + } + } + + items := make([]*pb.PurchaseStatsByProductItem, 0, len(statsMap)) + for productId, s := range statsMap { + avgPrice := 0.0 + if s.totalQty > 0 { + avgPrice = s.totalAmount / s.totalQty + } + items = append(items, &pb.PurchaseStatsByProductItem{ + ProductId: productId, + ProductName: s.productName, + Spec: s.spec, + Color: s.color, + TotalQty: fmt.Sprintf("%.2f", s.totalQty), + AvgUnitPrice: fmt.Sprintf("%.2f", avgPrice), + TotalAmount: fmt.Sprintf("%.2f", s.totalAmount), + }) + } + return &pb.PurchaseStatsByProductResp{List: items}, nil +} diff --git a/rpc/purchase/internal/logic/getpurchasestatsbysupplierlogic.go b/rpc/purchase/internal/logic/getpurchasestatsbysupplierlogic.go new file mode 100644 index 0000000..564dc58 --- /dev/null +++ b/rpc/purchase/internal/logic/getpurchasestatsbysupplierlogic.go @@ -0,0 +1,67 @@ +package logic + +import ( + "context" + "fmt" + + "muyu-apiserver/pkg/tenantctx" + "muyu-apiserver/rpc/purchase/internal/svc" + "muyu-apiserver/rpc/purchase/pb" + + "github.com/zeromicro/go-zero/core/logx" +) + +type GetPurchaseStatsBySupplierLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewGetPurchaseStatsBySupplierLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetPurchaseStatsBySupplierLogic { + return &GetPurchaseStatsBySupplierLogic{ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx)} +} + +func (l *GetPurchaseStatsBySupplierLogic) GetPurchaseStatsBySupplier(in *pb.PurchaseStatsSummaryReq) (*pb.PurchaseStatsBySupplierResp, error) { + tenantId := tenantctx.ExtractTenantId(l.ctx) + + orders, _, err := l.svcCtx.OrderModel.FindList(l.ctx, tenantId, 1, 10000, "", -1, in.StartDate, in.EndDate) + if err != nil { + return nil, err + } + + type supplierStats struct { + purchaseAmount float64 + paidAmount float64 + orderCount int64 + } + statsMap := map[string]*supplierStats{} + for _, o := range orders { + if o.Status == 2 { + continue + } + s := statsMap[o.SupplierId] + if s == nil { + s = &supplierStats{} + statsMap[o.SupplierId] = s + } + s.purchaseAmount += o.ContractAmount + s.paidAmount += o.PaidAmount + s.orderCount++ + } + + items := make([]*pb.PurchaseStatsBySupplierItem, 0, len(statsMap)) + for supplierId, s := range statsMap { + name := "" + if sup, err := l.svcCtx.SupplierModel.FindOneBySupplierId(l.ctx, supplierId); err == nil { + name = sup.SupplierName + } + items = append(items, &pb.PurchaseStatsBySupplierItem{ + SupplierId: supplierId, + SupplierName: name, + PurchaseAmount: fmt.Sprintf("%.2f", s.purchaseAmount), + PaidAmount: fmt.Sprintf("%.2f", s.paidAmount), + OrderCount: s.orderCount, + }) + } + return &pb.PurchaseStatsBySupplierResp{List: items}, nil +} diff --git a/rpc/purchase/internal/logic/getpurchasestatssummarylogic.go b/rpc/purchase/internal/logic/getpurchasestatssummarylogic.go new file mode 100644 index 0000000..35b1303 --- /dev/null +++ b/rpc/purchase/internal/logic/getpurchasestatssummarylogic.go @@ -0,0 +1,58 @@ +package logic + +import ( + "context" + "fmt" + + "muyu-apiserver/pkg/tenantctx" + "muyu-apiserver/rpc/purchase/internal/svc" + "muyu-apiserver/rpc/purchase/pb" + + "github.com/zeromicro/go-zero/core/logx" +) + +type GetPurchaseStatsSummaryLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewGetPurchaseStatsSummaryLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetPurchaseStatsSummaryLogic { + return &GetPurchaseStatsSummaryLogic{ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx)} +} + +func (l *GetPurchaseStatsSummaryLogic) GetPurchaseStatsSummary(in *pb.PurchaseStatsSummaryReq) (*pb.PurchaseStatsSummaryResp, error) { + tenantId := tenantctx.ExtractTenantId(l.ctx) + + // Use existing FindList to aggregate; page/pageSize 0 means fetch all + orders, _, err := l.svcCtx.OrderModel.FindList(l.ctx, tenantId, 1, 10000, "", -1, in.StartDate, in.EndDate) + if err != nil { + return nil, err + } + + var totalPurchase, totalPaid float64 + var orderCount int64 + for _, o := range orders { + if o.Status == 2 { + continue // skip cancelled + } + totalPurchase += o.ContractAmount + totalPaid += o.PaidAmount + orderCount++ + } + + receipts, total, err := l.svcCtx.ReceiptModel.FindList(l.ctx, tenantId, 1, 1, "", -1, in.StartDate, in.EndDate) + _ = receipts + receiptCount := int64(0) + if err == nil { + receiptCount = total + } + + return &pb.PurchaseStatsSummaryResp{ + TotalPurchaseAmount: fmt.Sprintf("%.2f", totalPurchase), + TotalPaidAmount: fmt.Sprintf("%.2f", totalPaid), + TotalUnpaidAmount: fmt.Sprintf("%.2f", totalPurchase-totalPaid), + OrderCount: orderCount, + ReceiptCount: receiptCount, + }, nil +} diff --git a/rpc/purchase/internal/logic/getsupplierlogic.go b/rpc/purchase/internal/logic/getsupplierlogic.go new file mode 100644 index 0000000..fc393e7 --- /dev/null +++ b/rpc/purchase/internal/logic/getsupplierlogic.go @@ -0,0 +1,41 @@ +package logic + +import ( + "context" + "fmt" + + "muyu-apiserver/rpc/purchase/internal/svc" + "muyu-apiserver/rpc/purchase/pb" + + "github.com/zeromicro/go-zero/core/logx" +) + +type GetSupplierLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewGetSupplierLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetSupplierLogic { + return &GetSupplierLogic{ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx)} +} + +func (l *GetSupplierLogic) GetSupplier(in *pb.GetSupplierReq) (*pb.SupplierInfo, error) { + s, err := l.svcCtx.SupplierModel.FindOneBySupplierId(l.ctx, in.SupplierId) + if err != nil { + return nil, ErrSupplierNotFound + } + return &pb.SupplierInfo{ + SupplierId: s.SupplierId, + SupplierName: s.SupplierName, + Phone: s.Phone, + PurchaseCount: s.PurchaseCount, + DeliveredQty: fmt.Sprintf("%.2f", s.DeliveredQty), + PayableAmount: fmt.Sprintf("%.2f", s.PayableAmount), + PaidAmount: fmt.Sprintf("%.2f", s.PaidAmount), + Status: s.Status, + Remark: s.Remark.String, + CreatedAt: s.CreatedAt.Format("2006-01-02 15:04:05"), + UpdatedAt: s.UpdatedAt.Format("2006-01-02 15:04:05"), + }, nil +} diff --git a/rpc/purchase/internal/logic/listinventoryloglogic.go b/rpc/purchase/internal/logic/listinventoryloglogic.go new file mode 100644 index 0000000..e44a0a8 --- /dev/null +++ b/rpc/purchase/internal/logic/listinventoryloglogic.go @@ -0,0 +1,48 @@ +package logic + +import ( + "context" + "fmt" + + "muyu-apiserver/pkg/tenantctx" + "muyu-apiserver/rpc/purchase/internal/svc" + "muyu-apiserver/rpc/purchase/pb" + + "github.com/zeromicro/go-zero/core/logx" +) + +type ListInventoryLogLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewListInventoryLogLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ListInventoryLogLogic { + return &ListInventoryLogLogic{ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx)} +} + +func (l *ListInventoryLogLogic) ListInventoryLog(in *pb.ListInventoryLogReq) (*pb.ListInventoryLogResp, error) { + tenantId := tenantctx.ExtractTenantId(l.ctx) + list, total, err := l.svcCtx.InventoryLogModel.FindList(l.ctx, tenantId, in.Page, in.PageSize, in.ProductId, in.RefType, in.ChangeType, in.StartDate, in.EndDate) + if err != nil { + return nil, err + } + items := make([]*pb.InventoryLogInfo, 0, len(list)) + for _, lg := range list { + items = append(items, &pb.InventoryLogInfo{ + LogId: lg.LogId, + ProductId: lg.ProductId, + ChangeQty: fmt.Sprintf("%.2f", lg.ChangeQty), + BalanceAfter: fmt.Sprintf("%.2f", lg.BalanceAfter), + ChangeType: lg.ChangeType, + RefType: lg.RefType, + RefId: lg.RefId, + ContactId: lg.ContactId, + LogDate: lg.LogDate.Format("2006-01-02"), + Operator: lg.Operator, + Remark: lg.Remark.String, + CreatedAt: lg.CreatedAt.Format("2006-01-02 15:04:05"), + }) + } + return &pb.ListInventoryLogResp{Total: total, List: items}, nil +} diff --git a/rpc/purchase/internal/logic/listpurchaseorderlogic.go b/rpc/purchase/internal/logic/listpurchaseorderlogic.go new file mode 100644 index 0000000..36d1ee7 --- /dev/null +++ b/rpc/purchase/internal/logic/listpurchaseorderlogic.go @@ -0,0 +1,65 @@ +package logic + +import ( + "context" + "fmt" + + "muyu-apiserver/pkg/tenantctx" + "muyu-apiserver/rpc/purchase/internal/svc" + "muyu-apiserver/rpc/purchase/pb" + + "github.com/zeromicro/go-zero/core/logx" +) + +type ListPurchaseOrderLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewListPurchaseOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ListPurchaseOrderLogic { + return &ListPurchaseOrderLogic{ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx)} +} + +func (l *ListPurchaseOrderLogic) ListPurchaseOrder(in *pb.ListPurchaseOrderReq) (*pb.ListPurchaseOrderResp, error) { + tenantId := tenantctx.ExtractTenantId(l.ctx) + status := in.Status + if status == 0 { + status = -1 + } + list, total, err := l.svcCtx.OrderModel.FindList(l.ctx, tenantId, in.Page, in.PageSize, in.SupplierId, status, in.StartDate, in.EndDate) + if err != nil { + return nil, err + } + + // Build supplier name cache + supplierNames := map[string]string{} + items := make([]*pb.PurchaseOrderInfo, 0, len(list)) + for _, o := range list { + if _, ok := supplierNames[o.SupplierId]; !ok { + if s, err := l.svcCtx.SupplierModel.FindOneBySupplierId(l.ctx, o.SupplierId); err == nil { + supplierNames[o.SupplierId] = s.SupplierName + } + } + items = append(items, &pb.PurchaseOrderInfo{ + OrderId: o.OrderId, + OrderNo: o.OrderNo, + SupplierId: o.SupplierId, + SupplierName: supplierNames[o.SupplierId], + OrderDate: o.OrderDate.Format("2006-01-02"), + ContractAmount: fmt.Sprintf("%.2f", o.ContractAmount), + ReceivedQty: fmt.Sprintf("%.2f", o.ReceivedQty), + PaidAmount: fmt.Sprintf("%.2f", o.PaidAmount), + PaymentStatus: o.PaymentStatus, + ReceiptStatus: o.ReceiptStatus, + PurchaseBy: o.PurchaseBy, + Creator: o.Creator, + Operator: o.Operator, + Status: o.Status, + Remark: o.Remark.String, + CreatedAt: o.CreatedAt.Format("2006-01-02 15:04:05"), + UpdatedAt: o.UpdatedAt.Format("2006-01-02 15:04:05"), + }) + } + return &pb.ListPurchaseOrderResp{Total: total, List: items}, nil +} diff --git a/rpc/purchase/internal/logic/listpurchasepaymentlogic.go b/rpc/purchase/internal/logic/listpurchasepaymentlogic.go new file mode 100644 index 0000000..f050141 --- /dev/null +++ b/rpc/purchase/internal/logic/listpurchasepaymentlogic.go @@ -0,0 +1,45 @@ +package logic + +import ( + "context" + "fmt" + + "muyu-apiserver/pkg/tenantctx" + "muyu-apiserver/rpc/purchase/internal/svc" + "muyu-apiserver/rpc/purchase/pb" + + "github.com/zeromicro/go-zero/core/logx" +) + +type ListPurchasePaymentLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewListPurchasePaymentLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ListPurchasePaymentLogic { + return &ListPurchasePaymentLogic{ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx)} +} + +func (l *ListPurchasePaymentLogic) ListPurchasePayment(in *pb.ListPurchasePaymentReq) (*pb.ListPurchasePaymentResp, error) { + tenantId := tenantctx.ExtractTenantId(l.ctx) + list, total, err := l.svcCtx.PaymentModel.FindList(l.ctx, tenantId, in.Page, in.PageSize, in.OrderId, in.SupplierId, in.StartDate, in.EndDate) + if err != nil { + return nil, err + } + items := make([]*pb.PurchasePaymentInfo, 0, len(list)) + for _, p := range list { + items = append(items, &pb.PurchasePaymentInfo{ + PaymentId: p.PaymentId, + OrderId: p.OrderId, + SupplierId: p.SupplierId, + PaymentDate: p.PaymentDate.Format("2006-01-02"), + Amount: fmt.Sprintf("%.2f", p.Amount), + PaymentMethod: p.PaymentMethod, + Operator: p.Operator, + Remark: p.Remark.String, + CreatedAt: p.CreatedAt.Format("2006-01-02 15:04:05"), + }) + } + return &pb.ListPurchasePaymentResp{Total: total, List: items}, nil +} diff --git a/rpc/purchase/internal/logic/listpurchasereceiptlogic.go b/rpc/purchase/internal/logic/listpurchasereceiptlogic.go new file mode 100644 index 0000000..88a73b7 --- /dev/null +++ b/rpc/purchase/internal/logic/listpurchasereceiptlogic.go @@ -0,0 +1,49 @@ +package logic + +import ( + "context" + "fmt" + + "muyu-apiserver/pkg/tenantctx" + "muyu-apiserver/rpc/purchase/internal/svc" + "muyu-apiserver/rpc/purchase/pb" + + "github.com/zeromicro/go-zero/core/logx" +) + +type ListPurchaseReceiptLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewListPurchaseReceiptLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ListPurchaseReceiptLogic { + return &ListPurchaseReceiptLogic{ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx)} +} + +func (l *ListPurchaseReceiptLogic) ListPurchaseReceipt(in *pb.ListPurchaseReceiptReq) (*pb.ListPurchaseReceiptResp, error) { + tenantId := tenantctx.ExtractTenantId(l.ctx) + status := in.Status + if status == 0 { + status = -1 + } + list, total, err := l.svcCtx.ReceiptModel.FindList(l.ctx, tenantId, in.Page, in.PageSize, in.OrderId, status, in.StartDate, in.EndDate) + if err != nil { + return nil, err + } + items := make([]*pb.PurchaseReceiptInfo, 0, len(list)) + for _, r := range list { + items = append(items, &pb.PurchaseReceiptInfo{ + ReceiptId: r.ReceiptId, + ReceiptNo: r.ReceiptNo, + OrderId: r.OrderId, + ReceiptDate: r.ReceiptDate.Format("2006-01-02"), + ReceivedBy: r.ReceivedBy, + Status: r.Status, + Remark: r.Remark.String, + CreatedAt: r.CreatedAt.Format("2006-01-02 15:04:05"), + }) + } + _ = fmt.Sprintf // suppress unused import + return &pb.ListPurchaseReceiptResp{Total: total, List: items}, nil +} diff --git a/rpc/purchase/internal/logic/listsupplierlogic.go b/rpc/purchase/internal/logic/listsupplierlogic.go new file mode 100644 index 0000000..31109c0 --- /dev/null +++ b/rpc/purchase/internal/logic/listsupplierlogic.go @@ -0,0 +1,51 @@ +package logic + +import ( + "context" + "fmt" + + "muyu-apiserver/pkg/tenantctx" + "muyu-apiserver/rpc/purchase/internal/svc" + "muyu-apiserver/rpc/purchase/pb" + + "github.com/zeromicro/go-zero/core/logx" +) + +type ListSupplierLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewListSupplierLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ListSupplierLogic { + return &ListSupplierLogic{ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx)} +} + +func (l *ListSupplierLogic) ListSupplier(in *pb.ListSupplierReq) (*pb.ListSupplierResp, error) { + tenantId := tenantctx.ExtractTenantId(l.ctx) + status := in.Status + if status == 0 { + status = -1 + } + list, total, err := l.svcCtx.SupplierModel.FindList(l.ctx, tenantId, in.Page, in.PageSize, in.SupplierName, status) + if err != nil { + return nil, err + } + items := make([]*pb.SupplierInfo, 0, len(list)) + for _, s := range list { + items = append(items, &pb.SupplierInfo{ + SupplierId: s.SupplierId, + SupplierName: s.SupplierName, + Phone: s.Phone, + PurchaseCount: s.PurchaseCount, + DeliveredQty: fmt.Sprintf("%.2f", s.DeliveredQty), + PayableAmount: fmt.Sprintf("%.2f", s.PayableAmount), + PaidAmount: fmt.Sprintf("%.2f", s.PaidAmount), + Status: s.Status, + Remark: s.Remark.String, + CreatedAt: s.CreatedAt.Format("2006-01-02 15:04:05"), + UpdatedAt: s.UpdatedAt.Format("2006-01-02 15:04:05"), + }) + } + return &pb.ListSupplierResp{Total: total, List: items}, nil +} diff --git a/rpc/purchase/internal/logic/updatepurchaseorderlogic.go b/rpc/purchase/internal/logic/updatepurchaseorderlogic.go new file mode 100644 index 0000000..95bc6de --- /dev/null +++ b/rpc/purchase/internal/logic/updatepurchaseorderlogic.go @@ -0,0 +1,87 @@ +package logic + +import ( + "context" + "database/sql" + "strconv" + "time" + + "muyu-apiserver/model" + "muyu-apiserver/pkg/tenantctx" + "muyu-apiserver/pkg/uid" + "muyu-apiserver/rpc/purchase/internal/svc" + "muyu-apiserver/rpc/purchase/pb" + + "github.com/zeromicro/go-zero/core/logx" +) + +type UpdatePurchaseOrderLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewUpdatePurchaseOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdatePurchaseOrderLogic { + return &UpdatePurchaseOrderLogic{ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx)} +} + +func (l *UpdatePurchaseOrderLogic) UpdatePurchaseOrder(in *pb.UpdatePurchaseOrderReq) (*pb.Empty, error) { + tenantId := tenantctx.ExtractTenantId(l.ctx) + order, err := l.svcCtx.OrderModel.FindOneByOrderId(l.ctx, in.OrderId) + if err != nil { + return nil, ErrOrderNotFound + } + if order.Status != 0 { + return nil, ErrOrderNotDraft + } + + orderDate, err := time.Parse("2006-01-02", in.OrderDate) + if err != nil { + orderDate = order.OrderDate + } + + var contractAmount float64 + for _, d := range in.Details { + qty, _ := strconv.ParseFloat(d.Quantity, 64) + price, _ := strconv.ParseFloat(d.UnitPrice, 64) + contractAmount += qty * price + } + + order.SupplierId = in.SupplierId + order.OrderDate = orderDate + order.ContractAmount = contractAmount + order.PurchaseBy = in.PurchaseBy + order.Operator = tenantId + order.Remark = sql.NullString{String: in.Remark, Valid: in.Remark != ""} + + if err := l.svcCtx.OrderModel.Update(l.ctx, order); err != nil { + return nil, err + } + + // Replace details + if err := l.svcCtx.OrderDetailModel.DeleteByOrderId(l.ctx, in.OrderId); err != nil { + return nil, err + } + details := make([]*model.PurPurchaseOrderDetail, 0, len(in.Details)) + for _, d := range in.Details { + qty, _ := strconv.ParseFloat(d.Quantity, 64) + price, _ := strconv.ParseFloat(d.UnitPrice, 64) + details = append(details, &model.PurPurchaseOrderDetail{ + DetailId: uid.Generate(), + TenantId: tenantId, + OrderId: in.OrderId, + ProductId: d.ProductId, + ProductName: d.ProductName, + Spec: d.Spec, + Color: d.Color, + Quantity: qty, + UnitPrice: price, + Amount: qty * price, + Remark: sql.NullString{String: d.Remark, Valid: d.Remark != ""}, + }) + } + if err := l.svcCtx.OrderDetailModel.BulkInsert(l.ctx, details); err != nil { + return nil, err + } + return &pb.Empty{}, nil +} diff --git a/rpc/purchase/internal/logic/updatesupplierlogic.go b/rpc/purchase/internal/logic/updatesupplierlogic.go new file mode 100644 index 0000000..c4e2df2 --- /dev/null +++ b/rpc/purchase/internal/logic/updatesupplierlogic.go @@ -0,0 +1,38 @@ +package logic + +import ( + "context" + "database/sql" + + "muyu-apiserver/rpc/purchase/internal/svc" + "muyu-apiserver/rpc/purchase/pb" + + "github.com/zeromicro/go-zero/core/logx" +) + +type UpdateSupplierLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewUpdateSupplierLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateSupplierLogic { + return &UpdateSupplierLogic{ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx)} +} + +func (l *UpdateSupplierLogic) UpdateSupplier(in *pb.UpdateSupplierReq) (*pb.Empty, error) { + s, err := l.svcCtx.SupplierModel.FindOneBySupplierId(l.ctx, in.SupplierId) + if err != nil { + return nil, ErrSupplierNotFound + } + + s.SupplierName = in.SupplierName + s.Phone = in.Phone + s.Status = in.Status + s.Remark = sql.NullString{String: in.Remark, Valid: in.Remark != ""} + + if err := l.svcCtx.SupplierModel.Update(l.ctx, s); err != nil { + return nil, err + } + return &pb.Empty{}, nil +} diff --git a/rpc/purchase/internal/server/purchaseserviceserver.go b/rpc/purchase/internal/server/purchaseserviceserver.go new file mode 100644 index 0000000..8240297 --- /dev/null +++ b/rpc/purchase/internal/server/purchaseserviceserver.go @@ -0,0 +1,102 @@ +package server + +import ( + "context" + + "muyu-apiserver/rpc/purchase/internal/logic" + "muyu-apiserver/rpc/purchase/internal/svc" + "muyu-apiserver/rpc/purchase/pb" +) + +type PurchaseServiceServer struct { + svcCtx *svc.ServiceContext + pb.UnimplementedPurchaseServiceServer +} + +func NewPurchaseServiceServer(svcCtx *svc.ServiceContext) *PurchaseServiceServer { + return &PurchaseServiceServer{svcCtx: svcCtx} +} + +func (s *PurchaseServiceServer) CreateSupplier(ctx context.Context, in *pb.CreateSupplierReq) (*pb.IdResp, error) { + return logic.NewCreateSupplierLogic(ctx, s.svcCtx).CreateSupplier(in) +} + +func (s *PurchaseServiceServer) UpdateSupplier(ctx context.Context, in *pb.UpdateSupplierReq) (*pb.Empty, error) { + return logic.NewUpdateSupplierLogic(ctx, s.svcCtx).UpdateSupplier(in) +} + +func (s *PurchaseServiceServer) DeleteSupplier(ctx context.Context, in *pb.DeleteSupplierReq) (*pb.Empty, error) { + return logic.NewDeleteSupplierLogic(ctx, s.svcCtx).DeleteSupplier(in) +} + +func (s *PurchaseServiceServer) GetSupplier(ctx context.Context, in *pb.GetSupplierReq) (*pb.SupplierInfo, error) { + return logic.NewGetSupplierLogic(ctx, s.svcCtx).GetSupplier(in) +} + +func (s *PurchaseServiceServer) ListSupplier(ctx context.Context, in *pb.ListSupplierReq) (*pb.ListSupplierResp, error) { + return logic.NewListSupplierLogic(ctx, s.svcCtx).ListSupplier(in) +} + +func (s *PurchaseServiceServer) CreatePurchaseOrder(ctx context.Context, in *pb.CreatePurchaseOrderReq) (*pb.IdResp, error) { + return logic.NewCreatePurchaseOrderLogic(ctx, s.svcCtx).CreatePurchaseOrder(in) +} + +func (s *PurchaseServiceServer) UpdatePurchaseOrder(ctx context.Context, in *pb.UpdatePurchaseOrderReq) (*pb.Empty, error) { + return logic.NewUpdatePurchaseOrderLogic(ctx, s.svcCtx).UpdatePurchaseOrder(in) +} + +func (s *PurchaseServiceServer) ConfirmPurchaseOrder(ctx context.Context, in *pb.ConfirmPurchaseOrderReq) (*pb.Empty, error) { + return logic.NewConfirmPurchaseOrderLogic(ctx, s.svcCtx).ConfirmPurchaseOrder(in) +} + +func (s *PurchaseServiceServer) CancelPurchaseOrder(ctx context.Context, in *pb.CancelPurchaseOrderReq) (*pb.Empty, error) { + return logic.NewCancelPurchaseOrderLogic(ctx, s.svcCtx).CancelPurchaseOrder(in) +} + +func (s *PurchaseServiceServer) GetPurchaseOrder(ctx context.Context, in *pb.GetPurchaseOrderReq) (*pb.PurchaseOrderInfo, error) { + return logic.NewGetPurchaseOrderLogic(ctx, s.svcCtx).GetPurchaseOrder(in) +} + +func (s *PurchaseServiceServer) ListPurchaseOrder(ctx context.Context, in *pb.ListPurchaseOrderReq) (*pb.ListPurchaseOrderResp, error) { + return logic.NewListPurchaseOrderLogic(ctx, s.svcCtx).ListPurchaseOrder(in) +} + +func (s *PurchaseServiceServer) CreatePurchaseReceipt(ctx context.Context, in *pb.CreatePurchaseReceiptReq) (*pb.IdResp, error) { + return logic.NewCreatePurchaseReceiptLogic(ctx, s.svcCtx).CreatePurchaseReceipt(in) +} + +func (s *PurchaseServiceServer) ConfirmPurchaseReceipt(ctx context.Context, in *pb.ConfirmPurchaseReceiptReq) (*pb.Empty, error) { + return logic.NewConfirmPurchaseReceiptLogic(ctx, s.svcCtx).ConfirmPurchaseReceipt(in) +} + +func (s *PurchaseServiceServer) GetPurchaseReceipt(ctx context.Context, in *pb.GetPurchaseReceiptReq) (*pb.PurchaseReceiptInfo, error) { + return logic.NewGetPurchaseReceiptLogic(ctx, s.svcCtx).GetPurchaseReceipt(in) +} + +func (s *PurchaseServiceServer) ListPurchaseReceipt(ctx context.Context, in *pb.ListPurchaseReceiptReq) (*pb.ListPurchaseReceiptResp, error) { + return logic.NewListPurchaseReceiptLogic(ctx, s.svcCtx).ListPurchaseReceipt(in) +} + +func (s *PurchaseServiceServer) CreatePurchasePayment(ctx context.Context, in *pb.CreatePurchasePaymentReq) (*pb.IdResp, error) { + return logic.NewCreatePurchasePaymentLogic(ctx, s.svcCtx).CreatePurchasePayment(in) +} + +func (s *PurchaseServiceServer) ListPurchasePayment(ctx context.Context, in *pb.ListPurchasePaymentReq) (*pb.ListPurchasePaymentResp, error) { + return logic.NewListPurchasePaymentLogic(ctx, s.svcCtx).ListPurchasePayment(in) +} + +func (s *PurchaseServiceServer) ListInventoryLog(ctx context.Context, in *pb.ListInventoryLogReq) (*pb.ListInventoryLogResp, error) { + return logic.NewListInventoryLogLogic(ctx, s.svcCtx).ListInventoryLog(in) +} + +func (s *PurchaseServiceServer) GetPurchaseStatsSummary(ctx context.Context, in *pb.PurchaseStatsSummaryReq) (*pb.PurchaseStatsSummaryResp, error) { + return logic.NewGetPurchaseStatsSummaryLogic(ctx, s.svcCtx).GetPurchaseStatsSummary(in) +} + +func (s *PurchaseServiceServer) GetPurchaseStatsBySupplier(ctx context.Context, in *pb.PurchaseStatsSummaryReq) (*pb.PurchaseStatsBySupplierResp, error) { + return logic.NewGetPurchaseStatsBySupplierLogic(ctx, s.svcCtx).GetPurchaseStatsBySupplier(in) +} + +func (s *PurchaseServiceServer) GetPurchaseStatsByProduct(ctx context.Context, in *pb.PurchaseStatsSummaryReq) (*pb.PurchaseStatsByProductResp, error) { + return logic.NewGetPurchaseStatsByProductLogic(ctx, s.svcCtx).GetPurchaseStatsByProduct(in) +} diff --git a/rpc/purchase/internal/svc/servicecontext.go b/rpc/purchase/internal/svc/servicecontext.go new file mode 100644 index 0000000..5a21875 --- /dev/null +++ b/rpc/purchase/internal/svc/servicecontext.go @@ -0,0 +1,33 @@ +package svc + +import ( + "muyu-apiserver/model" + "muyu-apiserver/rpc/purchase/internal/config" + + "github.com/zeromicro/go-zero/core/stores/sqlx" +) + +type ServiceContext struct { + Config config.Config + SupplierModel model.PurSupplierModel + OrderModel model.PurPurchaseOrderModel + OrderDetailModel model.PurPurchaseOrderDetailModel + ReceiptModel model.PurPurchaseReceiptModel + ReceiptDetailModel model.PurPurchaseReceiptDetailModel + PaymentModel model.PurPurchasePaymentModel + InventoryLogModel model.InvInventoryLogModel +} + +func NewServiceContext(c config.Config) *ServiceContext { + conn := sqlx.NewMysql(c.DataSource) + return &ServiceContext{ + Config: c, + SupplierModel: model.NewPurSupplierModel(conn, c.Cache), + OrderModel: model.NewPurPurchaseOrderModel(conn, c.Cache), + OrderDetailModel: model.NewPurPurchaseOrderDetailModel(conn), + ReceiptModel: model.NewPurPurchaseReceiptModel(conn), + ReceiptDetailModel: model.NewPurPurchaseReceiptDetailModel(conn), + PaymentModel: model.NewPurPurchasePaymentModel(conn), + InventoryLogModel: model.NewInvInventoryLogModel(conn), + } +} diff --git a/rpc/purchase/pb/purchase.pb.go b/rpc/purchase/pb/purchase.pb.go new file mode 100644 index 0000000..d819ed1 --- /dev/null +++ b/rpc/purchase/pb/purchase.pb.go @@ -0,0 +1,320 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: purchase.proto + +package pb + +// SupplierInfo holds supplier data returned from RPC. +type SupplierInfo struct { + SupplierId string `protobuf:"bytes,1,opt,name=supplier_id,json=supplierId,proto3" json:"supplier_id,omitempty"` + SupplierName string `protobuf:"bytes,2,opt,name=supplier_name,json=supplierName,proto3" json:"supplier_name,omitempty"` + Phone string `protobuf:"bytes,3,opt,name=phone,proto3" json:"phone,omitempty"` + PurchaseCount int64 `protobuf:"varint,4,opt,name=purchase_count,json=purchaseCount,proto3" json:"purchase_count,omitempty"` + DeliveredQty string `protobuf:"bytes,5,opt,name=delivered_qty,json=deliveredQty,proto3" json:"delivered_qty,omitempty"` + PayableAmount string `protobuf:"bytes,6,opt,name=payable_amount,json=payableAmount,proto3" json:"payable_amount,omitempty"` + PaidAmount string `protobuf:"bytes,7,opt,name=paid_amount,json=paidAmount,proto3" json:"paid_amount,omitempty"` + Status int64 `protobuf:"varint,8,opt,name=status,proto3" json:"status,omitempty"` + Remark string `protobuf:"bytes,9,opt,name=remark,proto3" json:"remark,omitempty"` + CreatedAt string `protobuf:"bytes,10,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + UpdatedAt string `protobuf:"bytes,11,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` +} + +type CreateSupplierReq struct { + SupplierName string `protobuf:"bytes,1,opt,name=supplier_name,json=supplierName,proto3" json:"supplier_name,omitempty"` + Phone string `protobuf:"bytes,2,opt,name=phone,proto3" json:"phone,omitempty"` + Remark string `protobuf:"bytes,3,opt,name=remark,proto3" json:"remark,omitempty"` +} + +type UpdateSupplierReq struct { + SupplierId string `protobuf:"bytes,1,opt,name=supplier_id,json=supplierId,proto3" json:"supplier_id,omitempty"` + SupplierName string `protobuf:"bytes,2,opt,name=supplier_name,json=supplierName,proto3" json:"supplier_name,omitempty"` + Phone string `protobuf:"bytes,3,opt,name=phone,proto3" json:"phone,omitempty"` + Status int64 `protobuf:"varint,4,opt,name=status,proto3" json:"status,omitempty"` + Remark string `protobuf:"bytes,5,opt,name=remark,proto3" json:"remark,omitempty"` +} + +type DeleteSupplierReq struct { + SupplierId string `protobuf:"bytes,1,opt,name=supplier_id,json=supplierId,proto3" json:"supplier_id,omitempty"` +} + +type GetSupplierReq struct { + SupplierId string `protobuf:"bytes,1,opt,name=supplier_id,json=supplierId,proto3" json:"supplier_id,omitempty"` +} + +type ListSupplierReq struct { + Page int64 `protobuf:"varint,1,opt,name=page,proto3" json:"page,omitempty"` + PageSize int64 `protobuf:"varint,2,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` + SupplierName string `protobuf:"bytes,3,opt,name=supplier_name,json=supplierName,proto3" json:"supplier_name,omitempty"` + Status int64 `protobuf:"varint,4,opt,name=status,proto3" json:"status,omitempty"` +} + +type ListSupplierResp struct { + Total int64 `protobuf:"varint,1,opt,name=total,proto3" json:"total,omitempty"` + List []*SupplierInfo `protobuf:"bytes,2,rep,name=list,proto3" json:"list,omitempty"` +} + +// PurchaseOrder +type PurchaseOrderInfo struct { + OrderId string `protobuf:"bytes,1,opt,name=order_id,json=orderId,proto3" json:"order_id,omitempty"` + OrderNo string `protobuf:"bytes,2,opt,name=order_no,json=orderNo,proto3" json:"order_no,omitempty"` + SupplierId string `protobuf:"bytes,3,opt,name=supplier_id,json=supplierId,proto3" json:"supplier_id,omitempty"` + SupplierName string `protobuf:"bytes,4,opt,name=supplier_name,json=supplierName,proto3" json:"supplier_name,omitempty"` + OrderDate string `protobuf:"bytes,5,opt,name=order_date,json=orderDate,proto3" json:"order_date,omitempty"` + ContractAmount string `protobuf:"bytes,6,opt,name=contract_amount,json=contractAmount,proto3" json:"contract_amount,omitempty"` + ReceivedQty string `protobuf:"bytes,7,opt,name=received_qty,json=receivedQty,proto3" json:"received_qty,omitempty"` + PaidAmount string `protobuf:"bytes,8,opt,name=paid_amount,json=paidAmount,proto3" json:"paid_amount,omitempty"` + PaymentStatus int64 `protobuf:"varint,9,opt,name=payment_status,json=paymentStatus,proto3" json:"payment_status,omitempty"` + ReceiptStatus int64 `protobuf:"varint,10,opt,name=receipt_status,json=receiptStatus,proto3" json:"receipt_status,omitempty"` + PurchaseBy string `protobuf:"bytes,11,opt,name=purchase_by,json=purchaseBy,proto3" json:"purchase_by,omitempty"` + Creator string `protobuf:"bytes,12,opt,name=creator,proto3" json:"creator,omitempty"` + Operator string `protobuf:"bytes,13,opt,name=operator,proto3" json:"operator,omitempty"` + Status int64 `protobuf:"varint,14,opt,name=status,proto3" json:"status,omitempty"` + Remark string `protobuf:"bytes,15,opt,name=remark,proto3" json:"remark,omitempty"` + CreatedAt string `protobuf:"bytes,16,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + UpdatedAt string `protobuf:"bytes,17,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` + Details []*PurchaseOrderDetailInfo `protobuf:"bytes,18,rep,name=details,proto3" json:"details,omitempty"` +} + +type PurchaseOrderDetailInfo struct { + DetailId string `protobuf:"bytes,1,opt,name=detail_id,json=detailId,proto3" json:"detail_id,omitempty"` + OrderId string `protobuf:"bytes,2,opt,name=order_id,json=orderId,proto3" json:"order_id,omitempty"` + ProductId string `protobuf:"bytes,3,opt,name=product_id,json=productId,proto3" json:"product_id,omitempty"` + ProductName string `protobuf:"bytes,4,opt,name=product_name,json=productName,proto3" json:"product_name,omitempty"` + Spec string `protobuf:"bytes,5,opt,name=spec,proto3" json:"spec,omitempty"` + Color string `protobuf:"bytes,6,opt,name=color,proto3" json:"color,omitempty"` + Quantity string `protobuf:"bytes,7,opt,name=quantity,proto3" json:"quantity,omitempty"` + UnitPrice string `protobuf:"bytes,8,opt,name=unit_price,json=unitPrice,proto3" json:"unit_price,omitempty"` + Amount string `protobuf:"bytes,9,opt,name=amount,proto3" json:"amount,omitempty"` + ReceivedQty string `protobuf:"bytes,10,opt,name=received_qty,json=receivedQty,proto3" json:"received_qty,omitempty"` + Remark string `protobuf:"bytes,11,opt,name=remark,proto3" json:"remark,omitempty"` +} + +type PurchaseOrderDetailReq struct { + ProductId string `protobuf:"bytes,1,opt,name=product_id,json=productId,proto3" json:"product_id,omitempty"` + ProductName string `protobuf:"bytes,2,opt,name=product_name,json=productName,proto3" json:"product_name,omitempty"` + Spec string `protobuf:"bytes,3,opt,name=spec,proto3" json:"spec,omitempty"` + Color string `protobuf:"bytes,4,opt,name=color,proto3" json:"color,omitempty"` + Quantity string `protobuf:"bytes,5,opt,name=quantity,proto3" json:"quantity,omitempty"` + UnitPrice string `protobuf:"bytes,6,opt,name=unit_price,json=unitPrice,proto3" json:"unit_price,omitempty"` + Remark string `protobuf:"bytes,7,opt,name=remark,proto3" json:"remark,omitempty"` +} + +type CreatePurchaseOrderReq struct { + SupplierId string `protobuf:"bytes,1,opt,name=supplier_id,json=supplierId,proto3" json:"supplier_id,omitempty"` + OrderDate string `protobuf:"bytes,2,opt,name=order_date,json=orderDate,proto3" json:"order_date,omitempty"` + PurchaseBy string `protobuf:"bytes,3,opt,name=purchase_by,json=purchaseBy,proto3" json:"purchase_by,omitempty"` + Remark string `protobuf:"bytes,4,opt,name=remark,proto3" json:"remark,omitempty"` + Details []*PurchaseOrderDetailReq `protobuf:"bytes,5,rep,name=details,proto3" json:"details,omitempty"` +} + +type UpdatePurchaseOrderReq struct { + OrderId string `protobuf:"bytes,1,opt,name=order_id,json=orderId,proto3" json:"order_id,omitempty"` + SupplierId string `protobuf:"bytes,2,opt,name=supplier_id,json=supplierId,proto3" json:"supplier_id,omitempty"` + OrderDate string `protobuf:"bytes,3,opt,name=order_date,json=orderDate,proto3" json:"order_date,omitempty"` + PurchaseBy string `protobuf:"bytes,4,opt,name=purchase_by,json=purchaseBy,proto3" json:"purchase_by,omitempty"` + Remark string `protobuf:"bytes,5,opt,name=remark,proto3" json:"remark,omitempty"` + Details []*PurchaseOrderDetailReq `protobuf:"bytes,6,rep,name=details,proto3" json:"details,omitempty"` +} + +type ConfirmPurchaseOrderReq struct { + OrderId string `protobuf:"bytes,1,opt,name=order_id,json=orderId,proto3" json:"order_id,omitempty"` +} + +type CancelPurchaseOrderReq struct { + OrderId string `protobuf:"bytes,1,opt,name=order_id,json=orderId,proto3" json:"order_id,omitempty"` +} + +type GetPurchaseOrderReq struct { + OrderId string `protobuf:"bytes,1,opt,name=order_id,json=orderId,proto3" json:"order_id,omitempty"` +} + +type ListPurchaseOrderReq struct { + Page int64 `protobuf:"varint,1,opt,name=page,proto3" json:"page,omitempty"` + PageSize int64 `protobuf:"varint,2,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` + SupplierId string `protobuf:"bytes,3,opt,name=supplier_id,json=supplierId,proto3" json:"supplier_id,omitempty"` + Status int64 `protobuf:"varint,4,opt,name=status,proto3" json:"status,omitempty"` + StartDate string `protobuf:"bytes,5,opt,name=start_date,json=startDate,proto3" json:"start_date,omitempty"` + EndDate string `protobuf:"bytes,6,opt,name=end_date,json=endDate,proto3" json:"end_date,omitempty"` +} + +type ListPurchaseOrderResp struct { + Total int64 `protobuf:"varint,1,opt,name=total,proto3" json:"total,omitempty"` + List []*PurchaseOrderInfo `protobuf:"bytes,2,rep,name=list,proto3" json:"list,omitempty"` +} + +// Receipt +type PurchaseReceiptInfo struct { + ReceiptId string `protobuf:"bytes,1,opt,name=receipt_id,json=receiptId,proto3" json:"receipt_id,omitempty"` + ReceiptNo string `protobuf:"bytes,2,opt,name=receipt_no,json=receiptNo,proto3" json:"receipt_no,omitempty"` + OrderId string `protobuf:"bytes,3,opt,name=order_id,json=orderId,proto3" json:"order_id,omitempty"` + ReceiptDate string `protobuf:"bytes,4,opt,name=receipt_date,json=receiptDate,proto3" json:"receipt_date,omitempty"` + ReceivedBy string `protobuf:"bytes,5,opt,name=received_by,json=receivedBy,proto3" json:"received_by,omitempty"` + Status int64 `protobuf:"varint,6,opt,name=status,proto3" json:"status,omitempty"` + Remark string `protobuf:"bytes,7,opt,name=remark,proto3" json:"remark,omitempty"` + CreatedAt string `protobuf:"bytes,8,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + Details []*PurchaseReceiptDetailInfo `protobuf:"bytes,9,rep,name=details,proto3" json:"details,omitempty"` +} + +type PurchaseReceiptDetailInfo struct { + DetailId string `protobuf:"bytes,1,opt,name=detail_id,json=detailId,proto3" json:"detail_id,omitempty"` + ReceiptId string `protobuf:"bytes,2,opt,name=receipt_id,json=receiptId,proto3" json:"receipt_id,omitempty"` + OrderDetailId string `protobuf:"bytes,3,opt,name=order_detail_id,json=orderDetailId,proto3" json:"order_detail_id,omitempty"` + ProductId string `protobuf:"bytes,4,opt,name=product_id,json=productId,proto3" json:"product_id,omitempty"` + ActualQty string `protobuf:"bytes,5,opt,name=actual_qty,json=actualQty,proto3" json:"actual_qty,omitempty"` + UnitCost string `protobuf:"bytes,6,opt,name=unit_cost,json=unitCost,proto3" json:"unit_cost,omitempty"` + Remark string `protobuf:"bytes,7,opt,name=remark,proto3" json:"remark,omitempty"` +} + +type PurchaseReceiptDetailReq struct { + OrderDetailId string `protobuf:"bytes,1,opt,name=order_detail_id,json=orderDetailId,proto3" json:"order_detail_id,omitempty"` + ProductId string `protobuf:"bytes,2,opt,name=product_id,json=productId,proto3" json:"product_id,omitempty"` + ActualQty string `protobuf:"bytes,3,opt,name=actual_qty,json=actualQty,proto3" json:"actual_qty,omitempty"` + UnitCost string `protobuf:"bytes,4,opt,name=unit_cost,json=unitCost,proto3" json:"unit_cost,omitempty"` + Remark string `protobuf:"bytes,5,opt,name=remark,proto3" json:"remark,omitempty"` +} + +type CreatePurchaseReceiptReq struct { + OrderId string `protobuf:"bytes,1,opt,name=order_id,json=orderId,proto3" json:"order_id,omitempty"` + ReceiptDate string `protobuf:"bytes,2,opt,name=receipt_date,json=receiptDate,proto3" json:"receipt_date,omitempty"` + ReceivedBy string `protobuf:"bytes,3,opt,name=received_by,json=receivedBy,proto3" json:"received_by,omitempty"` + Remark string `protobuf:"bytes,4,opt,name=remark,proto3" json:"remark,omitempty"` + Details []*PurchaseReceiptDetailReq `protobuf:"bytes,5,rep,name=details,proto3" json:"details,omitempty"` +} + +type ConfirmPurchaseReceiptReq struct { + ReceiptId string `protobuf:"bytes,1,opt,name=receipt_id,json=receiptId,proto3" json:"receipt_id,omitempty"` +} + +type GetPurchaseReceiptReq struct { + ReceiptId string `protobuf:"bytes,1,opt,name=receipt_id,json=receiptId,proto3" json:"receipt_id,omitempty"` +} + +type ListPurchaseReceiptReq struct { + Page int64 `protobuf:"varint,1,opt,name=page,proto3" json:"page,omitempty"` + PageSize int64 `protobuf:"varint,2,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` + OrderId string `protobuf:"bytes,3,opt,name=order_id,json=orderId,proto3" json:"order_id,omitempty"` + Status int64 `protobuf:"varint,4,opt,name=status,proto3" json:"status,omitempty"` + StartDate string `protobuf:"bytes,5,opt,name=start_date,json=startDate,proto3" json:"start_date,omitempty"` + EndDate string `protobuf:"bytes,6,opt,name=end_date,json=endDate,proto3" json:"end_date,omitempty"` +} + +type ListPurchaseReceiptResp struct { + Total int64 `protobuf:"varint,1,opt,name=total,proto3" json:"total,omitempty"` + List []*PurchaseReceiptInfo `protobuf:"bytes,2,rep,name=list,proto3" json:"list,omitempty"` +} + +// Payment +type PurchasePaymentInfo struct { + PaymentId string `protobuf:"bytes,1,opt,name=payment_id,json=paymentId,proto3" json:"payment_id,omitempty"` + OrderId string `protobuf:"bytes,2,opt,name=order_id,json=orderId,proto3" json:"order_id,omitempty"` + SupplierId string `protobuf:"bytes,3,opt,name=supplier_id,json=supplierId,proto3" json:"supplier_id,omitempty"` + PaymentDate string `protobuf:"bytes,4,opt,name=payment_date,json=paymentDate,proto3" json:"payment_date,omitempty"` + Amount string `protobuf:"bytes,5,opt,name=amount,proto3" json:"amount,omitempty"` + PaymentMethod string `protobuf:"bytes,6,opt,name=payment_method,json=paymentMethod,proto3" json:"payment_method,omitempty"` + Operator string `protobuf:"bytes,7,opt,name=operator,proto3" json:"operator,omitempty"` + Remark string `protobuf:"bytes,8,opt,name=remark,proto3" json:"remark,omitempty"` + CreatedAt string `protobuf:"bytes,9,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` +} + +type CreatePurchasePaymentReq struct { + OrderId string `protobuf:"bytes,1,opt,name=order_id,json=orderId,proto3" json:"order_id,omitempty"` + PaymentDate string `protobuf:"bytes,2,opt,name=payment_date,json=paymentDate,proto3" json:"payment_date,omitempty"` + Amount string `protobuf:"bytes,3,opt,name=amount,proto3" json:"amount,omitempty"` + PaymentMethod string `protobuf:"bytes,4,opt,name=payment_method,json=paymentMethod,proto3" json:"payment_method,omitempty"` + Remark string `protobuf:"bytes,5,opt,name=remark,proto3" json:"remark,omitempty"` +} + +type GetPurchasePaymentReq struct { + PaymentId string `protobuf:"bytes,1,opt,name=payment_id,json=paymentId,proto3" json:"payment_id,omitempty"` +} + +type ListPurchasePaymentReq struct { + Page int64 `protobuf:"varint,1,opt,name=page,proto3" json:"page,omitempty"` + PageSize int64 `protobuf:"varint,2,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` + OrderId string `protobuf:"bytes,3,opt,name=order_id,json=orderId,proto3" json:"order_id,omitempty"` + SupplierId string `protobuf:"bytes,4,opt,name=supplier_id,json=supplierId,proto3" json:"supplier_id,omitempty"` + StartDate string `protobuf:"bytes,5,opt,name=start_date,json=startDate,proto3" json:"start_date,omitempty"` + EndDate string `protobuf:"bytes,6,opt,name=end_date,json=endDate,proto3" json:"end_date,omitempty"` +} + +type ListPurchasePaymentResp struct { + Total int64 `protobuf:"varint,1,opt,name=total,proto3" json:"total,omitempty"` + List []*PurchasePaymentInfo `protobuf:"bytes,2,rep,name=list,proto3" json:"list,omitempty"` +} + +// InventoryLog +type InventoryLogInfo struct { + LogId string `protobuf:"bytes,1,opt,name=log_id,json=logId,proto3" json:"log_id,omitempty"` + ProductId string `protobuf:"bytes,2,opt,name=product_id,json=productId,proto3" json:"product_id,omitempty"` + ChangeQty string `protobuf:"bytes,3,opt,name=change_qty,json=changeQty,proto3" json:"change_qty,omitempty"` + BalanceAfter string `protobuf:"bytes,4,opt,name=balance_after,json=balanceAfter,proto3" json:"balance_after,omitempty"` + ChangeType int64 `protobuf:"varint,5,opt,name=change_type,json=changeType,proto3" json:"change_type,omitempty"` + RefType string `protobuf:"bytes,6,opt,name=ref_type,json=refType,proto3" json:"ref_type,omitempty"` + RefId string `protobuf:"bytes,7,opt,name=ref_id,json=refId,proto3" json:"ref_id,omitempty"` + ContactId string `protobuf:"bytes,8,opt,name=contact_id,json=contactId,proto3" json:"contact_id,omitempty"` + LogDate string `protobuf:"bytes,9,opt,name=log_date,json=logDate,proto3" json:"log_date,omitempty"` + Operator string `protobuf:"bytes,10,opt,name=operator,proto3" json:"operator,omitempty"` + Remark string `protobuf:"bytes,11,opt,name=remark,proto3" json:"remark,omitempty"` + CreatedAt string `protobuf:"bytes,12,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` +} + +type ListInventoryLogReq struct { + Page int64 `protobuf:"varint,1,opt,name=page,proto3" json:"page,omitempty"` + PageSize int64 `protobuf:"varint,2,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` + ProductId string `protobuf:"bytes,3,opt,name=product_id,json=productId,proto3" json:"product_id,omitempty"` + RefType string `protobuf:"bytes,4,opt,name=ref_type,json=refType,proto3" json:"ref_type,omitempty"` + ChangeType int64 `protobuf:"varint,5,opt,name=change_type,json=changeType,proto3" json:"change_type,omitempty"` + StartDate string `protobuf:"bytes,6,opt,name=start_date,json=startDate,proto3" json:"start_date,omitempty"` + EndDate string `protobuf:"bytes,7,opt,name=end_date,json=endDate,proto3" json:"end_date,omitempty"` +} + +type ListInventoryLogResp struct { + Total int64 `protobuf:"varint,1,opt,name=total,proto3" json:"total,omitempty"` + List []*InventoryLogInfo `protobuf:"bytes,2,rep,name=list,proto3" json:"list,omitempty"` +} + +// Stats +type PurchaseStatsSummaryReq struct { + StartDate string `protobuf:"bytes,1,opt,name=start_date,json=startDate,proto3" json:"start_date,omitempty"` + EndDate string `protobuf:"bytes,2,opt,name=end_date,json=endDate,proto3" json:"end_date,omitempty"` +} + +type PurchaseStatsSummaryResp struct { + TotalPurchaseAmount string `protobuf:"bytes,1,opt,name=total_purchase_amount,json=totalPurchaseAmount,proto3" json:"total_purchase_amount,omitempty"` + TotalPaidAmount string `protobuf:"bytes,2,opt,name=total_paid_amount,json=totalPaidAmount,proto3" json:"total_paid_amount,omitempty"` + TotalUnpaidAmount string `protobuf:"bytes,3,opt,name=total_unpaid_amount,json=totalUnpaidAmount,proto3" json:"total_unpaid_amount,omitempty"` + OrderCount int64 `protobuf:"varint,4,opt,name=order_count,json=orderCount,proto3" json:"order_count,omitempty"` + ReceiptCount int64 `protobuf:"varint,5,opt,name=receipt_count,json=receiptCount,proto3" json:"receipt_count,omitempty"` +} + +type PurchaseStatsBySupplierItem struct { + SupplierId string `protobuf:"bytes,1,opt,name=supplier_id,json=supplierId,proto3" json:"supplier_id,omitempty"` + SupplierName string `protobuf:"bytes,2,opt,name=supplier_name,json=supplierName,proto3" json:"supplier_name,omitempty"` + PurchaseAmount string `protobuf:"bytes,3,opt,name=purchase_amount,json=purchaseAmount,proto3" json:"purchase_amount,omitempty"` + PaidAmount string `protobuf:"bytes,4,opt,name=paid_amount,json=paidAmount,proto3" json:"paid_amount,omitempty"` + OrderCount int64 `protobuf:"varint,5,opt,name=order_count,json=orderCount,proto3" json:"order_count,omitempty"` +} + +type PurchaseStatsBySupplierResp struct { + List []*PurchaseStatsBySupplierItem `protobuf:"bytes,1,rep,name=list,proto3" json:"list,omitempty"` +} + +type PurchaseStatsByProductItem struct { + ProductId string `protobuf:"bytes,1,opt,name=product_id,json=productId,proto3" json:"product_id,omitempty"` + ProductName string `protobuf:"bytes,2,opt,name=product_name,json=productName,proto3" json:"product_name,omitempty"` + Spec string `protobuf:"bytes,3,opt,name=spec,proto3" json:"spec,omitempty"` + Color string `protobuf:"bytes,4,opt,name=color,proto3" json:"color,omitempty"` + TotalQty string `protobuf:"bytes,5,opt,name=total_qty,json=totalQty,proto3" json:"total_qty,omitempty"` + AvgUnitPrice string `protobuf:"bytes,6,opt,name=avg_unit_price,json=avgUnitPrice,proto3" json:"avg_unit_price,omitempty"` + TotalAmount string `protobuf:"bytes,7,opt,name=total_amount,json=totalAmount,proto3" json:"total_amount,omitempty"` +} + +type PurchaseStatsByProductResp struct { + List []*PurchaseStatsByProductItem `protobuf:"bytes,1,rep,name=list,proto3" json:"list,omitempty"` +} + +// Common +type IdResp struct { + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` +} + +type Empty struct{} diff --git a/rpc/purchase/pb/purchase_grpc.pb.go b/rpc/purchase/pb/purchase_grpc.pb.go new file mode 100644 index 0000000..a1a860d --- /dev/null +++ b/rpc/purchase/pb/purchase_grpc.pb.go @@ -0,0 +1,617 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// source: purchase.proto + +package pb + +import ( + "context" + + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +// PurchaseServiceClient is the client API for PurchaseService service. +type PurchaseServiceClient interface { + CreateSupplier(ctx context.Context, in *CreateSupplierReq, opts ...grpc.CallOption) (*IdResp, error) + UpdateSupplier(ctx context.Context, in *UpdateSupplierReq, opts ...grpc.CallOption) (*Empty, error) + DeleteSupplier(ctx context.Context, in *DeleteSupplierReq, opts ...grpc.CallOption) (*Empty, error) + GetSupplier(ctx context.Context, in *GetSupplierReq, opts ...grpc.CallOption) (*SupplierInfo, error) + ListSupplier(ctx context.Context, in *ListSupplierReq, opts ...grpc.CallOption) (*ListSupplierResp, error) + CreatePurchaseOrder(ctx context.Context, in *CreatePurchaseOrderReq, opts ...grpc.CallOption) (*IdResp, error) + UpdatePurchaseOrder(ctx context.Context, in *UpdatePurchaseOrderReq, opts ...grpc.CallOption) (*Empty, error) + ConfirmPurchaseOrder(ctx context.Context, in *ConfirmPurchaseOrderReq, opts ...grpc.CallOption) (*Empty, error) + CancelPurchaseOrder(ctx context.Context, in *CancelPurchaseOrderReq, opts ...grpc.CallOption) (*Empty, error) + GetPurchaseOrder(ctx context.Context, in *GetPurchaseOrderReq, opts ...grpc.CallOption) (*PurchaseOrderInfo, error) + ListPurchaseOrder(ctx context.Context, in *ListPurchaseOrderReq, opts ...grpc.CallOption) (*ListPurchaseOrderResp, error) + CreatePurchaseReceipt(ctx context.Context, in *CreatePurchaseReceiptReq, opts ...grpc.CallOption) (*IdResp, error) + ConfirmPurchaseReceipt(ctx context.Context, in *ConfirmPurchaseReceiptReq, opts ...grpc.CallOption) (*Empty, error) + GetPurchaseReceipt(ctx context.Context, in *GetPurchaseReceiptReq, opts ...grpc.CallOption) (*PurchaseReceiptInfo, error) + ListPurchaseReceipt(ctx context.Context, in *ListPurchaseReceiptReq, opts ...grpc.CallOption) (*ListPurchaseReceiptResp, error) + CreatePurchasePayment(ctx context.Context, in *CreatePurchasePaymentReq, opts ...grpc.CallOption) (*IdResp, error) + ListPurchasePayment(ctx context.Context, in *ListPurchasePaymentReq, opts ...grpc.CallOption) (*ListPurchasePaymentResp, error) + ListInventoryLog(ctx context.Context, in *ListInventoryLogReq, opts ...grpc.CallOption) (*ListInventoryLogResp, error) + GetPurchaseStatsSummary(ctx context.Context, in *PurchaseStatsSummaryReq, opts ...grpc.CallOption) (*PurchaseStatsSummaryResp, error) + GetPurchaseStatsBySupplier(ctx context.Context, in *PurchaseStatsSummaryReq, opts ...grpc.CallOption) (*PurchaseStatsBySupplierResp, error) + GetPurchaseStatsByProduct(ctx context.Context, in *PurchaseStatsSummaryReq, opts ...grpc.CallOption) (*PurchaseStatsByProductResp, error) +} + +type purchaseServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewPurchaseServiceClient(cc grpc.ClientConnInterface) PurchaseServiceClient { + return &purchaseServiceClient{cc} +} + +func (c *purchaseServiceClient) CreateSupplier(ctx context.Context, in *CreateSupplierReq, opts ...grpc.CallOption) (*IdResp, error) { + out := new(IdResp) + err := c.cc.Invoke(ctx, "/purchase.PurchaseService/CreateSupplier", in, out, opts...) + return out, err +} + +func (c *purchaseServiceClient) UpdateSupplier(ctx context.Context, in *UpdateSupplierReq, opts ...grpc.CallOption) (*Empty, error) { + out := new(Empty) + err := c.cc.Invoke(ctx, "/purchase.PurchaseService/UpdateSupplier", in, out, opts...) + return out, err +} + +func (c *purchaseServiceClient) DeleteSupplier(ctx context.Context, in *DeleteSupplierReq, opts ...grpc.CallOption) (*Empty, error) { + out := new(Empty) + err := c.cc.Invoke(ctx, "/purchase.PurchaseService/DeleteSupplier", in, out, opts...) + return out, err +} + +func (c *purchaseServiceClient) GetSupplier(ctx context.Context, in *GetSupplierReq, opts ...grpc.CallOption) (*SupplierInfo, error) { + out := new(SupplierInfo) + err := c.cc.Invoke(ctx, "/purchase.PurchaseService/GetSupplier", in, out, opts...) + return out, err +} + +func (c *purchaseServiceClient) ListSupplier(ctx context.Context, in *ListSupplierReq, opts ...grpc.CallOption) (*ListSupplierResp, error) { + out := new(ListSupplierResp) + err := c.cc.Invoke(ctx, "/purchase.PurchaseService/ListSupplier", in, out, opts...) + return out, err +} + +func (c *purchaseServiceClient) CreatePurchaseOrder(ctx context.Context, in *CreatePurchaseOrderReq, opts ...grpc.CallOption) (*IdResp, error) { + out := new(IdResp) + err := c.cc.Invoke(ctx, "/purchase.PurchaseService/CreatePurchaseOrder", in, out, opts...) + return out, err +} + +func (c *purchaseServiceClient) UpdatePurchaseOrder(ctx context.Context, in *UpdatePurchaseOrderReq, opts ...grpc.CallOption) (*Empty, error) { + out := new(Empty) + err := c.cc.Invoke(ctx, "/purchase.PurchaseService/UpdatePurchaseOrder", in, out, opts...) + return out, err +} + +func (c *purchaseServiceClient) ConfirmPurchaseOrder(ctx context.Context, in *ConfirmPurchaseOrderReq, opts ...grpc.CallOption) (*Empty, error) { + out := new(Empty) + err := c.cc.Invoke(ctx, "/purchase.PurchaseService/ConfirmPurchaseOrder", in, out, opts...) + return out, err +} + +func (c *purchaseServiceClient) CancelPurchaseOrder(ctx context.Context, in *CancelPurchaseOrderReq, opts ...grpc.CallOption) (*Empty, error) { + out := new(Empty) + err := c.cc.Invoke(ctx, "/purchase.PurchaseService/CancelPurchaseOrder", in, out, opts...) + return out, err +} + +func (c *purchaseServiceClient) GetPurchaseOrder(ctx context.Context, in *GetPurchaseOrderReq, opts ...grpc.CallOption) (*PurchaseOrderInfo, error) { + out := new(PurchaseOrderInfo) + err := c.cc.Invoke(ctx, "/purchase.PurchaseService/GetPurchaseOrder", in, out, opts...) + return out, err +} + +func (c *purchaseServiceClient) ListPurchaseOrder(ctx context.Context, in *ListPurchaseOrderReq, opts ...grpc.CallOption) (*ListPurchaseOrderResp, error) { + out := new(ListPurchaseOrderResp) + err := c.cc.Invoke(ctx, "/purchase.PurchaseService/ListPurchaseOrder", in, out, opts...) + return out, err +} + +func (c *purchaseServiceClient) CreatePurchaseReceipt(ctx context.Context, in *CreatePurchaseReceiptReq, opts ...grpc.CallOption) (*IdResp, error) { + out := new(IdResp) + err := c.cc.Invoke(ctx, "/purchase.PurchaseService/CreatePurchaseReceipt", in, out, opts...) + return out, err +} + +func (c *purchaseServiceClient) ConfirmPurchaseReceipt(ctx context.Context, in *ConfirmPurchaseReceiptReq, opts ...grpc.CallOption) (*Empty, error) { + out := new(Empty) + err := c.cc.Invoke(ctx, "/purchase.PurchaseService/ConfirmPurchaseReceipt", in, out, opts...) + return out, err +} + +func (c *purchaseServiceClient) GetPurchaseReceipt(ctx context.Context, in *GetPurchaseReceiptReq, opts ...grpc.CallOption) (*PurchaseReceiptInfo, error) { + out := new(PurchaseReceiptInfo) + err := c.cc.Invoke(ctx, "/purchase.PurchaseService/GetPurchaseReceipt", in, out, opts...) + return out, err +} + +func (c *purchaseServiceClient) ListPurchaseReceipt(ctx context.Context, in *ListPurchaseReceiptReq, opts ...grpc.CallOption) (*ListPurchaseReceiptResp, error) { + out := new(ListPurchaseReceiptResp) + err := c.cc.Invoke(ctx, "/purchase.PurchaseService/ListPurchaseReceipt", in, out, opts...) + return out, err +} + +func (c *purchaseServiceClient) CreatePurchasePayment(ctx context.Context, in *CreatePurchasePaymentReq, opts ...grpc.CallOption) (*IdResp, error) { + out := new(IdResp) + err := c.cc.Invoke(ctx, "/purchase.PurchaseService/CreatePurchasePayment", in, out, opts...) + return out, err +} + +func (c *purchaseServiceClient) ListPurchasePayment(ctx context.Context, in *ListPurchasePaymentReq, opts ...grpc.CallOption) (*ListPurchasePaymentResp, error) { + out := new(ListPurchasePaymentResp) + err := c.cc.Invoke(ctx, "/purchase.PurchaseService/ListPurchasePayment", in, out, opts...) + return out, err +} + +func (c *purchaseServiceClient) ListInventoryLog(ctx context.Context, in *ListInventoryLogReq, opts ...grpc.CallOption) (*ListInventoryLogResp, error) { + out := new(ListInventoryLogResp) + err := c.cc.Invoke(ctx, "/purchase.PurchaseService/ListInventoryLog", in, out, opts...) + return out, err +} + +func (c *purchaseServiceClient) GetPurchaseStatsSummary(ctx context.Context, in *PurchaseStatsSummaryReq, opts ...grpc.CallOption) (*PurchaseStatsSummaryResp, error) { + out := new(PurchaseStatsSummaryResp) + err := c.cc.Invoke(ctx, "/purchase.PurchaseService/GetPurchaseStatsSummary", in, out, opts...) + return out, err +} + +func (c *purchaseServiceClient) GetPurchaseStatsBySupplier(ctx context.Context, in *PurchaseStatsSummaryReq, opts ...grpc.CallOption) (*PurchaseStatsBySupplierResp, error) { + out := new(PurchaseStatsBySupplierResp) + err := c.cc.Invoke(ctx, "/purchase.PurchaseService/GetPurchaseStatsBySupplier", in, out, opts...) + return out, err +} + +func (c *purchaseServiceClient) GetPurchaseStatsByProduct(ctx context.Context, in *PurchaseStatsSummaryReq, opts ...grpc.CallOption) (*PurchaseStatsByProductResp, error) { + out := new(PurchaseStatsByProductResp) + err := c.cc.Invoke(ctx, "/purchase.PurchaseService/GetPurchaseStatsByProduct", in, out, opts...) + return out, err +} + +// PurchaseServiceServer is the server API for PurchaseService service. +type PurchaseServiceServer interface { + CreateSupplier(context.Context, *CreateSupplierReq) (*IdResp, error) + UpdateSupplier(context.Context, *UpdateSupplierReq) (*Empty, error) + DeleteSupplier(context.Context, *DeleteSupplierReq) (*Empty, error) + GetSupplier(context.Context, *GetSupplierReq) (*SupplierInfo, error) + ListSupplier(context.Context, *ListSupplierReq) (*ListSupplierResp, error) + CreatePurchaseOrder(context.Context, *CreatePurchaseOrderReq) (*IdResp, error) + UpdatePurchaseOrder(context.Context, *UpdatePurchaseOrderReq) (*Empty, error) + ConfirmPurchaseOrder(context.Context, *ConfirmPurchaseOrderReq) (*Empty, error) + CancelPurchaseOrder(context.Context, *CancelPurchaseOrderReq) (*Empty, error) + GetPurchaseOrder(context.Context, *GetPurchaseOrderReq) (*PurchaseOrderInfo, error) + ListPurchaseOrder(context.Context, *ListPurchaseOrderReq) (*ListPurchaseOrderResp, error) + CreatePurchaseReceipt(context.Context, *CreatePurchaseReceiptReq) (*IdResp, error) + ConfirmPurchaseReceipt(context.Context, *ConfirmPurchaseReceiptReq) (*Empty, error) + GetPurchaseReceipt(context.Context, *GetPurchaseReceiptReq) (*PurchaseReceiptInfo, error) + ListPurchaseReceipt(context.Context, *ListPurchaseReceiptReq) (*ListPurchaseReceiptResp, error) + CreatePurchasePayment(context.Context, *CreatePurchasePaymentReq) (*IdResp, error) + ListPurchasePayment(context.Context, *ListPurchasePaymentReq) (*ListPurchasePaymentResp, error) + ListInventoryLog(context.Context, *ListInventoryLogReq) (*ListInventoryLogResp, error) + GetPurchaseStatsSummary(context.Context, *PurchaseStatsSummaryReq) (*PurchaseStatsSummaryResp, error) + GetPurchaseStatsBySupplier(context.Context, *PurchaseStatsSummaryReq) (*PurchaseStatsBySupplierResp, error) + GetPurchaseStatsByProduct(context.Context, *PurchaseStatsSummaryReq) (*PurchaseStatsByProductResp, error) + mustEmbedUnimplementedPurchaseServiceServer() +} + +type UnimplementedPurchaseServiceServer struct{} + +func (UnimplementedPurchaseServiceServer) CreateSupplier(context.Context, *CreateSupplierReq) (*IdResp, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateSupplier not implemented") +} +func (UnimplementedPurchaseServiceServer) UpdateSupplier(context.Context, *UpdateSupplierReq) (*Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateSupplier not implemented") +} +func (UnimplementedPurchaseServiceServer) DeleteSupplier(context.Context, *DeleteSupplierReq) (*Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteSupplier not implemented") +} +func (UnimplementedPurchaseServiceServer) GetSupplier(context.Context, *GetSupplierReq) (*SupplierInfo, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetSupplier not implemented") +} +func (UnimplementedPurchaseServiceServer) ListSupplier(context.Context, *ListSupplierReq) (*ListSupplierResp, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListSupplier not implemented") +} +func (UnimplementedPurchaseServiceServer) CreatePurchaseOrder(context.Context, *CreatePurchaseOrderReq) (*IdResp, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreatePurchaseOrder not implemented") +} +func (UnimplementedPurchaseServiceServer) UpdatePurchaseOrder(context.Context, *UpdatePurchaseOrderReq) (*Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdatePurchaseOrder not implemented") +} +func (UnimplementedPurchaseServiceServer) ConfirmPurchaseOrder(context.Context, *ConfirmPurchaseOrderReq) (*Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method ConfirmPurchaseOrder not implemented") +} +func (UnimplementedPurchaseServiceServer) CancelPurchaseOrder(context.Context, *CancelPurchaseOrderReq) (*Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method CancelPurchaseOrder not implemented") +} +func (UnimplementedPurchaseServiceServer) GetPurchaseOrder(context.Context, *GetPurchaseOrderReq) (*PurchaseOrderInfo, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetPurchaseOrder not implemented") +} +func (UnimplementedPurchaseServiceServer) ListPurchaseOrder(context.Context, *ListPurchaseOrderReq) (*ListPurchaseOrderResp, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListPurchaseOrder not implemented") +} +func (UnimplementedPurchaseServiceServer) CreatePurchaseReceipt(context.Context, *CreatePurchaseReceiptReq) (*IdResp, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreatePurchaseReceipt not implemented") +} +func (UnimplementedPurchaseServiceServer) ConfirmPurchaseReceipt(context.Context, *ConfirmPurchaseReceiptReq) (*Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method ConfirmPurchaseReceipt not implemented") +} +func (UnimplementedPurchaseServiceServer) GetPurchaseReceipt(context.Context, *GetPurchaseReceiptReq) (*PurchaseReceiptInfo, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetPurchaseReceipt not implemented") +} +func (UnimplementedPurchaseServiceServer) ListPurchaseReceipt(context.Context, *ListPurchaseReceiptReq) (*ListPurchaseReceiptResp, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListPurchaseReceipt not implemented") +} +func (UnimplementedPurchaseServiceServer) CreatePurchasePayment(context.Context, *CreatePurchasePaymentReq) (*IdResp, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreatePurchasePayment not implemented") +} +func (UnimplementedPurchaseServiceServer) ListPurchasePayment(context.Context, *ListPurchasePaymentReq) (*ListPurchasePaymentResp, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListPurchasePayment not implemented") +} +func (UnimplementedPurchaseServiceServer) ListInventoryLog(context.Context, *ListInventoryLogReq) (*ListInventoryLogResp, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListInventoryLog not implemented") +} +func (UnimplementedPurchaseServiceServer) GetPurchaseStatsSummary(context.Context, *PurchaseStatsSummaryReq) (*PurchaseStatsSummaryResp, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetPurchaseStatsSummary not implemented") +} +func (UnimplementedPurchaseServiceServer) GetPurchaseStatsBySupplier(context.Context, *PurchaseStatsSummaryReq) (*PurchaseStatsBySupplierResp, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetPurchaseStatsBySupplier not implemented") +} +func (UnimplementedPurchaseServiceServer) GetPurchaseStatsByProduct(context.Context, *PurchaseStatsSummaryReq) (*PurchaseStatsByProductResp, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetPurchaseStatsByProduct not implemented") +} +func (UnimplementedPurchaseServiceServer) mustEmbedUnimplementedPurchaseServiceServer() {} + +type UnsafePurchaseServiceServer interface { + mustEmbedUnimplementedPurchaseServiceServer() +} + +func RegisterPurchaseServiceServer(s grpc.ServiceRegistrar, srv PurchaseServiceServer) { + s.RegisterService(&PurchaseService_ServiceDesc, srv) +} + +var PurchaseService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "purchase.PurchaseService", + HandlerType: (*PurchaseServiceServer)(nil), + Methods: []grpc.MethodDesc{ + {MethodName: "CreateSupplier", Handler: _PurchaseService_CreateSupplier_Handler}, + {MethodName: "UpdateSupplier", Handler: _PurchaseService_UpdateSupplier_Handler}, + {MethodName: "DeleteSupplier", Handler: _PurchaseService_DeleteSupplier_Handler}, + {MethodName: "GetSupplier", Handler: _PurchaseService_GetSupplier_Handler}, + {MethodName: "ListSupplier", Handler: _PurchaseService_ListSupplier_Handler}, + {MethodName: "CreatePurchaseOrder", Handler: _PurchaseService_CreatePurchaseOrder_Handler}, + {MethodName: "UpdatePurchaseOrder", Handler: _PurchaseService_UpdatePurchaseOrder_Handler}, + {MethodName: "ConfirmPurchaseOrder", Handler: _PurchaseService_ConfirmPurchaseOrder_Handler}, + {MethodName: "CancelPurchaseOrder", Handler: _PurchaseService_CancelPurchaseOrder_Handler}, + {MethodName: "GetPurchaseOrder", Handler: _PurchaseService_GetPurchaseOrder_Handler}, + {MethodName: "ListPurchaseOrder", Handler: _PurchaseService_ListPurchaseOrder_Handler}, + {MethodName: "CreatePurchaseReceipt", Handler: _PurchaseService_CreatePurchaseReceipt_Handler}, + {MethodName: "ConfirmPurchaseReceipt", Handler: _PurchaseService_ConfirmPurchaseReceipt_Handler}, + {MethodName: "GetPurchaseReceipt", Handler: _PurchaseService_GetPurchaseReceipt_Handler}, + {MethodName: "ListPurchaseReceipt", Handler: _PurchaseService_ListPurchaseReceipt_Handler}, + {MethodName: "CreatePurchasePayment", Handler: _PurchaseService_CreatePurchasePayment_Handler}, + {MethodName: "ListPurchasePayment", Handler: _PurchaseService_ListPurchasePayment_Handler}, + {MethodName: "ListInventoryLog", Handler: _PurchaseService_ListInventoryLog_Handler}, + {MethodName: "GetPurchaseStatsSummary", Handler: _PurchaseService_GetPurchaseStatsSummary_Handler}, + {MethodName: "GetPurchaseStatsBySupplier", Handler: _PurchaseService_GetPurchaseStatsBySupplier_Handler}, + {MethodName: "GetPurchaseStatsByProduct", Handler: _PurchaseService_GetPurchaseStatsByProduct_Handler}, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "purchase.proto", +} + +func _PurchaseService_CreateSupplier_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateSupplierReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PurchaseServiceServer).CreateSupplier(ctx, in) + } + info := &grpc.UnaryServerInfo{Server: srv, FullMethod: "/purchase.PurchaseService/CreateSupplier"} + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PurchaseServiceServer).CreateSupplier(ctx, req.(*CreateSupplierReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _PurchaseService_UpdateSupplier_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateSupplierReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PurchaseServiceServer).UpdateSupplier(ctx, in) + } + info := &grpc.UnaryServerInfo{Server: srv, FullMethod: "/purchase.PurchaseService/UpdateSupplier"} + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PurchaseServiceServer).UpdateSupplier(ctx, req.(*UpdateSupplierReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _PurchaseService_DeleteSupplier_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteSupplierReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PurchaseServiceServer).DeleteSupplier(ctx, in) + } + info := &grpc.UnaryServerInfo{Server: srv, FullMethod: "/purchase.PurchaseService/DeleteSupplier"} + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PurchaseServiceServer).DeleteSupplier(ctx, req.(*DeleteSupplierReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _PurchaseService_GetSupplier_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetSupplierReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PurchaseServiceServer).GetSupplier(ctx, in) + } + info := &grpc.UnaryServerInfo{Server: srv, FullMethod: "/purchase.PurchaseService/GetSupplier"} + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PurchaseServiceServer).GetSupplier(ctx, req.(*GetSupplierReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _PurchaseService_ListSupplier_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListSupplierReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PurchaseServiceServer).ListSupplier(ctx, in) + } + info := &grpc.UnaryServerInfo{Server: srv, FullMethod: "/purchase.PurchaseService/ListSupplier"} + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PurchaseServiceServer).ListSupplier(ctx, req.(*ListSupplierReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _PurchaseService_CreatePurchaseOrder_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreatePurchaseOrderReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PurchaseServiceServer).CreatePurchaseOrder(ctx, in) + } + info := &grpc.UnaryServerInfo{Server: srv, FullMethod: "/purchase.PurchaseService/CreatePurchaseOrder"} + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PurchaseServiceServer).CreatePurchaseOrder(ctx, req.(*CreatePurchaseOrderReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _PurchaseService_UpdatePurchaseOrder_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdatePurchaseOrderReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PurchaseServiceServer).UpdatePurchaseOrder(ctx, in) + } + info := &grpc.UnaryServerInfo{Server: srv, FullMethod: "/purchase.PurchaseService/UpdatePurchaseOrder"} + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PurchaseServiceServer).UpdatePurchaseOrder(ctx, req.(*UpdatePurchaseOrderReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _PurchaseService_ConfirmPurchaseOrder_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ConfirmPurchaseOrderReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PurchaseServiceServer).ConfirmPurchaseOrder(ctx, in) + } + info := &grpc.UnaryServerInfo{Server: srv, FullMethod: "/purchase.PurchaseService/ConfirmPurchaseOrder"} + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PurchaseServiceServer).ConfirmPurchaseOrder(ctx, req.(*ConfirmPurchaseOrderReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _PurchaseService_CancelPurchaseOrder_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CancelPurchaseOrderReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PurchaseServiceServer).CancelPurchaseOrder(ctx, in) + } + info := &grpc.UnaryServerInfo{Server: srv, FullMethod: "/purchase.PurchaseService/CancelPurchaseOrder"} + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PurchaseServiceServer).CancelPurchaseOrder(ctx, req.(*CancelPurchaseOrderReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _PurchaseService_GetPurchaseOrder_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetPurchaseOrderReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PurchaseServiceServer).GetPurchaseOrder(ctx, in) + } + info := &grpc.UnaryServerInfo{Server: srv, FullMethod: "/purchase.PurchaseService/GetPurchaseOrder"} + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PurchaseServiceServer).GetPurchaseOrder(ctx, req.(*GetPurchaseOrderReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _PurchaseService_ListPurchaseOrder_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListPurchaseOrderReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PurchaseServiceServer).ListPurchaseOrder(ctx, in) + } + info := &grpc.UnaryServerInfo{Server: srv, FullMethod: "/purchase.PurchaseService/ListPurchaseOrder"} + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PurchaseServiceServer).ListPurchaseOrder(ctx, req.(*ListPurchaseOrderReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _PurchaseService_CreatePurchaseReceipt_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreatePurchaseReceiptReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PurchaseServiceServer).CreatePurchaseReceipt(ctx, in) + } + info := &grpc.UnaryServerInfo{Server: srv, FullMethod: "/purchase.PurchaseService/CreatePurchaseReceipt"} + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PurchaseServiceServer).CreatePurchaseReceipt(ctx, req.(*CreatePurchaseReceiptReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _PurchaseService_ConfirmPurchaseReceipt_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ConfirmPurchaseReceiptReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PurchaseServiceServer).ConfirmPurchaseReceipt(ctx, in) + } + info := &grpc.UnaryServerInfo{Server: srv, FullMethod: "/purchase.PurchaseService/ConfirmPurchaseReceipt"} + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PurchaseServiceServer).ConfirmPurchaseReceipt(ctx, req.(*ConfirmPurchaseReceiptReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _PurchaseService_GetPurchaseReceipt_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetPurchaseReceiptReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PurchaseServiceServer).GetPurchaseReceipt(ctx, in) + } + info := &grpc.UnaryServerInfo{Server: srv, FullMethod: "/purchase.PurchaseService/GetPurchaseReceipt"} + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PurchaseServiceServer).GetPurchaseReceipt(ctx, req.(*GetPurchaseReceiptReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _PurchaseService_ListPurchaseReceipt_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListPurchaseReceiptReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PurchaseServiceServer).ListPurchaseReceipt(ctx, in) + } + info := &grpc.UnaryServerInfo{Server: srv, FullMethod: "/purchase.PurchaseService/ListPurchaseReceipt"} + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PurchaseServiceServer).ListPurchaseReceipt(ctx, req.(*ListPurchaseReceiptReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _PurchaseService_CreatePurchasePayment_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreatePurchasePaymentReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PurchaseServiceServer).CreatePurchasePayment(ctx, in) + } + info := &grpc.UnaryServerInfo{Server: srv, FullMethod: "/purchase.PurchaseService/CreatePurchasePayment"} + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PurchaseServiceServer).CreatePurchasePayment(ctx, req.(*CreatePurchasePaymentReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _PurchaseService_ListPurchasePayment_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListPurchasePaymentReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PurchaseServiceServer).ListPurchasePayment(ctx, in) + } + info := &grpc.UnaryServerInfo{Server: srv, FullMethod: "/purchase.PurchaseService/ListPurchasePayment"} + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PurchaseServiceServer).ListPurchasePayment(ctx, req.(*ListPurchasePaymentReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _PurchaseService_ListInventoryLog_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListInventoryLogReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PurchaseServiceServer).ListInventoryLog(ctx, in) + } + info := &grpc.UnaryServerInfo{Server: srv, FullMethod: "/purchase.PurchaseService/ListInventoryLog"} + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PurchaseServiceServer).ListInventoryLog(ctx, req.(*ListInventoryLogReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _PurchaseService_GetPurchaseStatsSummary_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PurchaseStatsSummaryReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PurchaseServiceServer).GetPurchaseStatsSummary(ctx, in) + } + info := &grpc.UnaryServerInfo{Server: srv, FullMethod: "/purchase.PurchaseService/GetPurchaseStatsSummary"} + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PurchaseServiceServer).GetPurchaseStatsSummary(ctx, req.(*PurchaseStatsSummaryReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _PurchaseService_GetPurchaseStatsBySupplier_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PurchaseStatsSummaryReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PurchaseServiceServer).GetPurchaseStatsBySupplier(ctx, in) + } + info := &grpc.UnaryServerInfo{Server: srv, FullMethod: "/purchase.PurchaseService/GetPurchaseStatsBySupplier"} + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PurchaseServiceServer).GetPurchaseStatsBySupplier(ctx, req.(*PurchaseStatsSummaryReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _PurchaseService_GetPurchaseStatsByProduct_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PurchaseStatsSummaryReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PurchaseServiceServer).GetPurchaseStatsByProduct(ctx, in) + } + info := &grpc.UnaryServerInfo{Server: srv, FullMethod: "/purchase.PurchaseService/GetPurchaseStatsByProduct"} + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PurchaseServiceServer).GetPurchaseStatsByProduct(ctx, req.(*PurchaseStatsSummaryReq)) + } + return interceptor(ctx, in, info, handler) +} diff --git a/rpc/purchase/purchase.go b/rpc/purchase/purchase.go new file mode 100644 index 0000000..59648bb --- /dev/null +++ b/rpc/purchase/purchase.go @@ -0,0 +1,43 @@ +package main + +import ( + "flag" + "fmt" + + "muyu-apiserver/pkg/metrics" + "muyu-apiserver/rpc/purchase/internal/config" + "muyu-apiserver/rpc/purchase/internal/server" + "muyu-apiserver/rpc/purchase/internal/svc" + "muyu-apiserver/rpc/purchase/pb" + + "github.com/zeromicro/go-zero/core/conf" + "github.com/zeromicro/go-zero/core/service" + "github.com/zeromicro/go-zero/zrpc" + "google.golang.org/grpc" + "google.golang.org/grpc/reflection" +) + +var configFile = flag.String("f", "etc/purchase.yaml", "the config file") + +func main() { + flag.Parse() + + var c config.Config + conf.MustLoad(*configFile, &c) + ctx := svc.NewServiceContext(c) + + metrics.StartHTTP(c.PrometheusAddr) + + s := zrpc.MustNewServer(c.RpcServerConf, func(grpcServer *grpc.Server) { + pb.RegisterPurchaseServiceServer(grpcServer, server.NewPurchaseServiceServer(ctx)) + + if c.Mode == service.DevMode || c.Mode == service.TestMode { + reflection.Register(grpcServer) + } + }) + s.AddUnaryInterceptors(metrics.UnaryServerInterceptor()) + defer s.Stop() + + fmt.Printf("Starting rpc server at %s...\n", c.ListenOn) + s.Start() +} diff --git a/rpc/purchase/purchase.proto b/rpc/purchase/purchase.proto new file mode 100644 index 0000000..26e61bc --- /dev/null +++ b/rpc/purchase/purchase.proto @@ -0,0 +1,365 @@ +syntax = "proto3"; + +package purchase; + +option go_package = "./pb"; + +// ==================== Supplier ==================== + +message SupplierInfo { + string supplier_id = 1; + string supplier_name = 2; + string phone = 3; + int64 purchase_count = 4; + string delivered_qty = 5; + string payable_amount = 6; + string paid_amount = 7; + int64 status = 8; + string remark = 9; + string created_at = 10; + string updated_at = 11; +} + +message CreateSupplierReq { + string supplier_name = 1; + string phone = 2; + string remark = 3; +} + +message UpdateSupplierReq { + string supplier_id = 1; + string supplier_name = 2; + string phone = 3; + int64 status = 4; + string remark = 5; +} + +message DeleteSupplierReq { + string supplier_id = 1; +} + +message GetSupplierReq { + string supplier_id = 1; +} + +message ListSupplierReq { + int64 page = 1; + int64 page_size = 2; + string supplier_name = 3; + int64 status = 4; +} + +message ListSupplierResp { + int64 total = 1; + repeated SupplierInfo list = 2; +} + +// ==================== PurchaseOrder ==================== + +message PurchaseOrderInfo { + string order_id = 1; + string order_no = 2; + string supplier_id = 3; + string supplier_name = 4; + string order_date = 5; + string contract_amount = 6; + string received_qty = 7; + string paid_amount = 8; + int64 payment_status = 9; + int64 receipt_status = 10; + string purchase_by = 11; + string creator = 12; + string operator = 13; + int64 status = 14; + string remark = 15; + string created_at = 16; + string updated_at = 17; + repeated PurchaseOrderDetailInfo details = 18; +} + +message PurchaseOrderDetailInfo { + string detail_id = 1; + string order_id = 2; + string product_id = 3; + string product_name = 4; + string spec = 5; + string color = 6; + string quantity = 7; + string unit_price = 8; + string amount = 9; + string received_qty = 10; + string remark = 11; +} + +message PurchaseOrderDetailReq { + string product_id = 1; + string product_name = 2; + string spec = 3; + string color = 4; + string quantity = 5; + string unit_price = 6; + string remark = 7; +} + +message CreatePurchaseOrderReq { + string supplier_id = 1; + string order_date = 2; + string purchase_by = 3; + string remark = 4; + repeated PurchaseOrderDetailReq details = 5; +} + +message UpdatePurchaseOrderReq { + string order_id = 1; + string supplier_id = 2; + string order_date = 3; + string purchase_by = 4; + string remark = 5; + repeated PurchaseOrderDetailReq details = 6; +} + +message ConfirmPurchaseOrderReq { + string order_id = 1; +} + +message CancelPurchaseOrderReq { + string order_id = 1; +} + +message GetPurchaseOrderReq { + string order_id = 1; +} + +message ListPurchaseOrderReq { + int64 page = 1; + int64 page_size = 2; + string supplier_id = 3; + int64 status = 4; + string start_date = 5; + string end_date = 6; +} + +message ListPurchaseOrderResp { + int64 total = 1; + repeated PurchaseOrderInfo list = 2; +} + +// ==================== PurchaseReceipt ==================== + +message PurchaseReceiptInfo { + string receipt_id = 1; + string receipt_no = 2; + string order_id = 3; + string receipt_date = 4; + string received_by = 5; + int64 status = 6; + string remark = 7; + string created_at = 8; + repeated PurchaseReceiptDetailInfo details = 9; +} + +message PurchaseReceiptDetailInfo { + string detail_id = 1; + string receipt_id = 2; + string order_detail_id = 3; + string product_id = 4; + string actual_qty = 5; + string unit_cost = 6; + string remark = 7; +} + +message PurchaseReceiptDetailReq { + string order_detail_id = 1; + string product_id = 2; + string actual_qty = 3; + string unit_cost = 4; + string remark = 5; +} + +message CreatePurchaseReceiptReq { + string order_id = 1; + string receipt_date = 2; + string received_by = 3; + string remark = 4; + repeated PurchaseReceiptDetailReq details = 5; +} + +message ConfirmPurchaseReceiptReq { + string receipt_id = 1; +} + +message GetPurchaseReceiptReq { + string receipt_id = 1; +} + +message ListPurchaseReceiptReq { + int64 page = 1; + int64 page_size = 2; + string order_id = 3; + int64 status = 4; + string start_date = 5; + string end_date = 6; +} + +message ListPurchaseReceiptResp { + int64 total = 1; + repeated PurchaseReceiptInfo list = 2; +} + +// ==================== PurchasePayment ==================== + +message PurchasePaymentInfo { + string payment_id = 1; + string order_id = 2; + string supplier_id = 3; + string payment_date = 4; + string amount = 5; + string payment_method = 6; + string operator = 7; + string remark = 8; + string created_at = 9; +} + +message CreatePurchasePaymentReq { + string order_id = 1; + string payment_date = 2; + string amount = 3; + string payment_method = 4; + string remark = 5; +} + +message GetPurchasePaymentReq { + string payment_id = 1; +} + +message ListPurchasePaymentReq { + int64 page = 1; + int64 page_size = 2; + string order_id = 3; + string supplier_id = 4; + string start_date = 5; + string end_date = 6; +} + +message ListPurchasePaymentResp { + int64 total = 1; + repeated PurchasePaymentInfo list = 2; +} + +// ==================== InventoryLog ==================== + +message InventoryLogInfo { + string log_id = 1; + string product_id = 2; + string change_qty = 3; + string balance_after = 4; + int64 change_type = 5; + string ref_type = 6; + string ref_id = 7; + string contact_id = 8; + string log_date = 9; + string operator = 10; + string remark = 11; + string created_at = 12; +} + +message ListInventoryLogReq { + int64 page = 1; + int64 page_size = 2; + string product_id = 3; + string ref_type = 4; + int64 change_type = 5; + string start_date = 6; + string end_date = 7; +} + +message ListInventoryLogResp { + int64 total = 1; + repeated InventoryLogInfo list = 2; +} + +// ==================== Stats ==================== + +message PurchaseStatsSummaryReq { + string start_date = 1; + string end_date = 2; +} + +message PurchaseStatsSummaryResp { + string total_purchase_amount = 1; + string total_paid_amount = 2; + string total_unpaid_amount = 3; + int64 order_count = 4; + int64 receipt_count = 5; +} + +message PurchaseStatsBySupplierItem { + string supplier_id = 1; + string supplier_name = 2; + string purchase_amount = 3; + string paid_amount = 4; + int64 order_count = 5; +} + +message PurchaseStatsBySupplierResp { + repeated PurchaseStatsBySupplierItem list = 1; +} + +message PurchaseStatsByProductItem { + string product_id = 1; + string product_name = 2; + string spec = 3; + string color = 4; + string total_qty = 5; + string avg_unit_price = 6; + string total_amount = 7; +} + +message PurchaseStatsByProductResp { + repeated PurchaseStatsByProductItem list = 1; +} + +// ==================== Common ==================== + +message IdResp { + string id = 1; +} + +message Empty {} + +// ==================== Service ==================== + +service PurchaseService { + // Supplier CRUD + rpc CreateSupplier(CreateSupplierReq) returns (IdResp); + rpc UpdateSupplier(UpdateSupplierReq) returns (Empty); + rpc DeleteSupplier(DeleteSupplierReq) returns (Empty); + rpc GetSupplier(GetSupplierReq) returns (SupplierInfo); + rpc ListSupplier(ListSupplierReq) returns (ListSupplierResp); + + // PurchaseOrder CRUD + status + rpc CreatePurchaseOrder(CreatePurchaseOrderReq) returns (IdResp); + rpc UpdatePurchaseOrder(UpdatePurchaseOrderReq) returns (Empty); + rpc ConfirmPurchaseOrder(ConfirmPurchaseOrderReq) returns (Empty); + rpc CancelPurchaseOrder(CancelPurchaseOrderReq) returns (Empty); + rpc GetPurchaseOrder(GetPurchaseOrderReq) returns (PurchaseOrderInfo); + rpc ListPurchaseOrder(ListPurchaseOrderReq) returns (ListPurchaseOrderResp); + + // Receipt + rpc CreatePurchaseReceipt(CreatePurchaseReceiptReq) returns (IdResp); + rpc ConfirmPurchaseReceipt(ConfirmPurchaseReceiptReq) returns (Empty); + rpc GetPurchaseReceipt(GetPurchaseReceiptReq) returns (PurchaseReceiptInfo); + rpc ListPurchaseReceipt(ListPurchaseReceiptReq) returns (ListPurchaseReceiptResp); + + // Payment + rpc CreatePurchasePayment(CreatePurchasePaymentReq) returns (IdResp); + rpc ListPurchasePayment(ListPurchasePaymentReq) returns (ListPurchasePaymentResp); + + // InventoryLog + rpc ListInventoryLog(ListInventoryLogReq) returns (ListInventoryLogResp); + + // Stats + rpc GetPurchaseStatsSummary(PurchaseStatsSummaryReq) returns (PurchaseStatsSummaryResp); + rpc GetPurchaseStatsBySupplier(PurchaseStatsSummaryReq) returns (PurchaseStatsBySupplierResp); + rpc GetPurchaseStatsByProduct(PurchaseStatsSummaryReq) returns (PurchaseStatsByProductResp); +} diff --git a/rpc/purchase/purchaseservice/purchaseservice.go b/rpc/purchase/purchaseservice/purchaseservice.go new file mode 100644 index 0000000..7466dea --- /dev/null +++ b/rpc/purchase/purchaseservice/purchaseservice.go @@ -0,0 +1,167 @@ +package purchaseservice + +import ( + "context" + + "muyu-apiserver/rpc/purchase/pb" + + "github.com/zeromicro/go-zero/zrpc" + "google.golang.org/grpc" +) + +type ( + CreateSupplierReq = pb.CreateSupplierReq + UpdateSupplierReq = pb.UpdateSupplierReq + DeleteSupplierReq = pb.DeleteSupplierReq + GetSupplierReq = pb.GetSupplierReq + ListSupplierReq = pb.ListSupplierReq + ListSupplierResp = pb.ListSupplierResp + SupplierInfo = pb.SupplierInfo + CreatePurchaseOrderReq = pb.CreatePurchaseOrderReq + UpdatePurchaseOrderReq = pb.UpdatePurchaseOrderReq + ConfirmPurchaseOrderReq = pb.ConfirmPurchaseOrderReq + CancelPurchaseOrderReq = pb.CancelPurchaseOrderReq + GetPurchaseOrderReq = pb.GetPurchaseOrderReq + ListPurchaseOrderReq = pb.ListPurchaseOrderReq + ListPurchaseOrderResp = pb.ListPurchaseOrderResp + PurchaseOrderInfo = pb.PurchaseOrderInfo + PurchaseOrderDetailReq = pb.PurchaseOrderDetailReq + PurchaseOrderDetailInfo = pb.PurchaseOrderDetailInfo + CreatePurchaseReceiptReq = pb.CreatePurchaseReceiptReq + ConfirmPurchaseReceiptReq = pb.ConfirmPurchaseReceiptReq + GetPurchaseReceiptReq = pb.GetPurchaseReceiptReq + ListPurchaseReceiptReq = pb.ListPurchaseReceiptReq + ListPurchaseReceiptResp = pb.ListPurchaseReceiptResp + PurchaseReceiptInfo = pb.PurchaseReceiptInfo + PurchaseReceiptDetailReq = pb.PurchaseReceiptDetailReq + PurchaseReceiptDetailInfo = pb.PurchaseReceiptDetailInfo + CreatePurchasePaymentReq = pb.CreatePurchasePaymentReq + ListPurchasePaymentReq = pb.ListPurchasePaymentReq + ListPurchasePaymentResp = pb.ListPurchasePaymentResp + PurchasePaymentInfo = pb.PurchasePaymentInfo + ListInventoryLogReq = pb.ListInventoryLogReq + ListInventoryLogResp = pb.ListInventoryLogResp + InventoryLogInfo = pb.InventoryLogInfo + PurchaseStatsSummaryReq = pb.PurchaseStatsSummaryReq + PurchaseStatsSummaryResp = pb.PurchaseStatsSummaryResp + PurchaseStatsBySupplierResp = pb.PurchaseStatsBySupplierResp + PurchaseStatsByProductResp = pb.PurchaseStatsByProductResp + IdResp = pb.IdResp + Empty = pb.Empty + + PurchaseService interface { + CreateSupplier(ctx context.Context, in *CreateSupplierReq, opts ...grpc.CallOption) (*IdResp, error) + UpdateSupplier(ctx context.Context, in *UpdateSupplierReq, opts ...grpc.CallOption) (*Empty, error) + DeleteSupplier(ctx context.Context, in *DeleteSupplierReq, opts ...grpc.CallOption) (*Empty, error) + GetSupplier(ctx context.Context, in *GetSupplierReq, opts ...grpc.CallOption) (*SupplierInfo, error) + ListSupplier(ctx context.Context, in *ListSupplierReq, opts ...grpc.CallOption) (*ListSupplierResp, error) + CreatePurchaseOrder(ctx context.Context, in *CreatePurchaseOrderReq, opts ...grpc.CallOption) (*IdResp, error) + UpdatePurchaseOrder(ctx context.Context, in *UpdatePurchaseOrderReq, opts ...grpc.CallOption) (*Empty, error) + ConfirmPurchaseOrder(ctx context.Context, in *ConfirmPurchaseOrderReq, opts ...grpc.CallOption) (*Empty, error) + CancelPurchaseOrder(ctx context.Context, in *CancelPurchaseOrderReq, opts ...grpc.CallOption) (*Empty, error) + GetPurchaseOrder(ctx context.Context, in *GetPurchaseOrderReq, opts ...grpc.CallOption) (*PurchaseOrderInfo, error) + ListPurchaseOrder(ctx context.Context, in *ListPurchaseOrderReq, opts ...grpc.CallOption) (*ListPurchaseOrderResp, error) + CreatePurchaseReceipt(ctx context.Context, in *CreatePurchaseReceiptReq, opts ...grpc.CallOption) (*IdResp, error) + ConfirmPurchaseReceipt(ctx context.Context, in *ConfirmPurchaseReceiptReq, opts ...grpc.CallOption) (*Empty, error) + GetPurchaseReceipt(ctx context.Context, in *GetPurchaseReceiptReq, opts ...grpc.CallOption) (*PurchaseReceiptInfo, error) + ListPurchaseReceipt(ctx context.Context, in *ListPurchaseReceiptReq, opts ...grpc.CallOption) (*ListPurchaseReceiptResp, error) + CreatePurchasePayment(ctx context.Context, in *CreatePurchasePaymentReq, opts ...grpc.CallOption) (*IdResp, error) + ListPurchasePayment(ctx context.Context, in *ListPurchasePaymentReq, opts ...grpc.CallOption) (*ListPurchasePaymentResp, error) + ListInventoryLog(ctx context.Context, in *ListInventoryLogReq, opts ...grpc.CallOption) (*ListInventoryLogResp, error) + GetPurchaseStatsSummary(ctx context.Context, in *PurchaseStatsSummaryReq, opts ...grpc.CallOption) (*PurchaseStatsSummaryResp, error) + GetPurchaseStatsBySupplier(ctx context.Context, in *PurchaseStatsSummaryReq, opts ...grpc.CallOption) (*PurchaseStatsBySupplierResp, error) + GetPurchaseStatsByProduct(ctx context.Context, in *PurchaseStatsSummaryReq, opts ...grpc.CallOption) (*PurchaseStatsByProductResp, error) + } + + defaultPurchaseService struct { + cli zrpc.Client + } +) + +func NewPurchaseService(cli zrpc.Client) PurchaseService { + return &defaultPurchaseService{cli: cli} +} + +func (m *defaultPurchaseService) CreateSupplier(ctx context.Context, in *CreateSupplierReq, opts ...grpc.CallOption) (*IdResp, error) { + return pb.NewPurchaseServiceClient(m.cli.Conn()).CreateSupplier(ctx, in, opts...) +} + +func (m *defaultPurchaseService) UpdateSupplier(ctx context.Context, in *UpdateSupplierReq, opts ...grpc.CallOption) (*Empty, error) { + return pb.NewPurchaseServiceClient(m.cli.Conn()).UpdateSupplier(ctx, in, opts...) +} + +func (m *defaultPurchaseService) DeleteSupplier(ctx context.Context, in *DeleteSupplierReq, opts ...grpc.CallOption) (*Empty, error) { + return pb.NewPurchaseServiceClient(m.cli.Conn()).DeleteSupplier(ctx, in, opts...) +} + +func (m *defaultPurchaseService) GetSupplier(ctx context.Context, in *GetSupplierReq, opts ...grpc.CallOption) (*SupplierInfo, error) { + return pb.NewPurchaseServiceClient(m.cli.Conn()).GetSupplier(ctx, in, opts...) +} + +func (m *defaultPurchaseService) ListSupplier(ctx context.Context, in *ListSupplierReq, opts ...grpc.CallOption) (*ListSupplierResp, error) { + return pb.NewPurchaseServiceClient(m.cli.Conn()).ListSupplier(ctx, in, opts...) +} + +func (m *defaultPurchaseService) CreatePurchaseOrder(ctx context.Context, in *CreatePurchaseOrderReq, opts ...grpc.CallOption) (*IdResp, error) { + return pb.NewPurchaseServiceClient(m.cli.Conn()).CreatePurchaseOrder(ctx, in, opts...) +} + +func (m *defaultPurchaseService) UpdatePurchaseOrder(ctx context.Context, in *UpdatePurchaseOrderReq, opts ...grpc.CallOption) (*Empty, error) { + return pb.NewPurchaseServiceClient(m.cli.Conn()).UpdatePurchaseOrder(ctx, in, opts...) +} + +func (m *defaultPurchaseService) ConfirmPurchaseOrder(ctx context.Context, in *ConfirmPurchaseOrderReq, opts ...grpc.CallOption) (*Empty, error) { + return pb.NewPurchaseServiceClient(m.cli.Conn()).ConfirmPurchaseOrder(ctx, in, opts...) +} + +func (m *defaultPurchaseService) CancelPurchaseOrder(ctx context.Context, in *CancelPurchaseOrderReq, opts ...grpc.CallOption) (*Empty, error) { + return pb.NewPurchaseServiceClient(m.cli.Conn()).CancelPurchaseOrder(ctx, in, opts...) +} + +func (m *defaultPurchaseService) GetPurchaseOrder(ctx context.Context, in *GetPurchaseOrderReq, opts ...grpc.CallOption) (*PurchaseOrderInfo, error) { + return pb.NewPurchaseServiceClient(m.cli.Conn()).GetPurchaseOrder(ctx, in, opts...) +} + +func (m *defaultPurchaseService) ListPurchaseOrder(ctx context.Context, in *ListPurchaseOrderReq, opts ...grpc.CallOption) (*ListPurchaseOrderResp, error) { + return pb.NewPurchaseServiceClient(m.cli.Conn()).ListPurchaseOrder(ctx, in, opts...) +} + +func (m *defaultPurchaseService) CreatePurchaseReceipt(ctx context.Context, in *CreatePurchaseReceiptReq, opts ...grpc.CallOption) (*IdResp, error) { + return pb.NewPurchaseServiceClient(m.cli.Conn()).CreatePurchaseReceipt(ctx, in, opts...) +} + +func (m *defaultPurchaseService) ConfirmPurchaseReceipt(ctx context.Context, in *ConfirmPurchaseReceiptReq, opts ...grpc.CallOption) (*Empty, error) { + return pb.NewPurchaseServiceClient(m.cli.Conn()).ConfirmPurchaseReceipt(ctx, in, opts...) +} + +func (m *defaultPurchaseService) GetPurchaseReceipt(ctx context.Context, in *GetPurchaseReceiptReq, opts ...grpc.CallOption) (*PurchaseReceiptInfo, error) { + return pb.NewPurchaseServiceClient(m.cli.Conn()).GetPurchaseReceipt(ctx, in, opts...) +} + +func (m *defaultPurchaseService) ListPurchaseReceipt(ctx context.Context, in *ListPurchaseReceiptReq, opts ...grpc.CallOption) (*ListPurchaseReceiptResp, error) { + return pb.NewPurchaseServiceClient(m.cli.Conn()).ListPurchaseReceipt(ctx, in, opts...) +} + +func (m *defaultPurchaseService) CreatePurchasePayment(ctx context.Context, in *CreatePurchasePaymentReq, opts ...grpc.CallOption) (*IdResp, error) { + return pb.NewPurchaseServiceClient(m.cli.Conn()).CreatePurchasePayment(ctx, in, opts...) +} + +func (m *defaultPurchaseService) ListPurchasePayment(ctx context.Context, in *ListPurchasePaymentReq, opts ...grpc.CallOption) (*ListPurchasePaymentResp, error) { + return pb.NewPurchaseServiceClient(m.cli.Conn()).ListPurchasePayment(ctx, in, opts...) +} + +func (m *defaultPurchaseService) ListInventoryLog(ctx context.Context, in *ListInventoryLogReq, opts ...grpc.CallOption) (*ListInventoryLogResp, error) { + return pb.NewPurchaseServiceClient(m.cli.Conn()).ListInventoryLog(ctx, in, opts...) +} + +func (m *defaultPurchaseService) GetPurchaseStatsSummary(ctx context.Context, in *PurchaseStatsSummaryReq, opts ...grpc.CallOption) (*PurchaseStatsSummaryResp, error) { + return pb.NewPurchaseServiceClient(m.cli.Conn()).GetPurchaseStatsSummary(ctx, in, opts...) +} + +func (m *defaultPurchaseService) GetPurchaseStatsBySupplier(ctx context.Context, in *PurchaseStatsSummaryReq, opts ...grpc.CallOption) (*PurchaseStatsBySupplierResp, error) { + return pb.NewPurchaseServiceClient(m.cli.Conn()).GetPurchaseStatsBySupplier(ctx, in, opts...) +} + +func (m *defaultPurchaseService) GetPurchaseStatsByProduct(ctx context.Context, in *PurchaseStatsSummaryReq, opts ...grpc.CallOption) (*PurchaseStatsByProductResp, error) { + return pb.NewPurchaseServiceClient(m.cli.Conn()).GetPurchaseStatsByProduct(ctx, in, opts...) +}