16

我一直在审查主要的开源 ERP 产品。我要求 ERP 提供财务会计、销售、采购、制造/仓库和库存功能。我一直在研究这些特性中的每一个支持什么,与他们的演示进行简短的交互,查看他们的高级技术架构,并对他们的一些源代码进行抽样。

我希望找到一个系统,它不会因为过于复杂的库而过于臃肿,展现出一些将持久性、域逻辑和表示分离的分层(MVC 也是可选的),定制或扩展不是很麻烦,并且展现出一些干净,经过深思熟虑的关系表结构。本质上,介于原始组织的 php 或客户端/服务器与臃肿的 J2EE 之间。我也喜欢一个设计良好但缺少一些功能的系统,而不是一个设计糟糕的系统,它涵盖了我需要的所有功能。

我希望在下面回答的问题:

  • 现在有什么(至少有一些用途)?
  • 什么是 ERP 系统的一套不错的特定功能(什么应该是单独的产品)?
  • 对其技术架构的高水平(有偏见的)反应,以及围绕使用的技术堆栈的势头。
  • 每个系统的详细示例,显示典型的代码风格和组织。
  • 对其核心关系表设计的初步批评
  • 社区活动、支持、动力?
4

4 回答 4

12

OpenERP - 优雅和简单。蟒蛇,Javascript。很好的分层和模块化,但使用轻量级框架。只希望它不使用 ORM。技术概述。关键文件:. 源代码库:serveraddonsweball-in-one。关键源目录:/openerp/addons

erpNext - 有趣。Python。比 OpenERP 的模块化程度要低一些。技术依赖结构、网络笔记框架概述。关键文件:. 源代码和网络笔记框架代码。主要源目录:

OpenBravo - 分层良好,使用了一些重量级的框架。爪哇。技术概述。关键文件:. 源代码。关键源目录:/src-db/database/model、/src/erpCommon/[info、ad_process、ad_callouts、ad_actionButtons、ad_forms、ad_reports]、/src/org/openbravo/erpReports

opentaps - 分层良好的重量级框架。爪哇。技术概述。关键文件:. 源代码。关键源目录:/application/*/[data, entitydef, servicedef, src, scripts, webapp, widget], /opentaps/[crmsfa, finances, purchase, warehouse]

PostBooks - 有点简单的实现,具有良好的组织,但希望它有更多的层次。在 GUI 客户端中对对象的一些很好的使用。我不喜欢在客户端代码中大量使用 pgpsql 数据库编程语言和内联 sql。C++、Pgpsql、Javascript。技术概述。关键文件:. 源代码。关键源目录:/xtuple/[guiclient, share/reports], /xtuple/[functions, metasql, misc/postbooks_empty.backup, triggers, types, views]

WebERP - 非常简单的实现,意味着任何人都可以修改它。这也意味着它没有那么好分层或模块化。程序 PHP,没有框架。技术概述基础结构。关键文件:. 源代码。关键源目录:/、/includes、/sql/mysql/weberp-new.sql

于 2013-05-25T06:29:35.767 回答
1

这些项目分为 4 个家庭,其中一些完全独立于一个家庭。

  • Compiere -> Adiempiere、OpenBravo、Adaxa、SocrateOpen、A1.io
  • TinyERP -> OpenERP, Tryton
  • WebERP -> FrontAccounting
  • OFBiz -> opentaps
  • 邮书
  • ERP下一个

(ERP5 看起来很有趣,但已经死了。如果 GnuE 获得动力,它可能会很有趣。JFire,SQL Ledger 家族只是没有足够的功能来成为一个完整的 ERP)

除了维基百科的列表和个别产品文章,您还可以在以下站点找到评论和列表:

于 2013-05-25T05:15:56.730 回答
0

对于针对制造和食品加工的 ERP,这些似乎是一个有用的、最小化的功能集:

  • 会计/财务 - 分类帐、应付帐款、应收帐款、现金、固定资产、财务报表、税收
  • 制造、仓库 - 工作订单、制造物料清单、物料请求、任务、序列/批次跟踪、包装、项目转换/生产
  • 库存 - 接收、运输、实物库存、项目站点、项目转移
  • 采购 - 采购申请、采购订单、待处理订单
  • 销售——销售订单、销售发票
  • 物料需求计划 - 生产计划、主生产计划、物料需求计划、预定订单

这些似乎更好地由专业产品提供或在需要时添加:

  • 销售 - 订单和发票以外的任何东西
  • 财务规划/分析
  • 物料请求计划 - 产能计划、约束管理
  • CRM/服务管理/营销
  • 项目管理
  • 人力资源
  • 电子商务
  • POS

根据审查编译:

于 2013-05-25T05:27:14.210 回答
0

表格/对象设计的一些样本:

Ledger(下面有的好像用了line和entry table,有的没有,需要进一步研究)

打开水龙头

   AcctgTransEntry
            title="Transaction Entry Entity">
      acctgTransId" type="id-ne"
      acctgTransEntrySeqId" type="id-ne"
      acctgTransEntryTypeId" type="id-ne"
      description" type="description"
      voucherRef" type="short-varchar"
      partyId" type="id"
      roleTypeId" type="id"
      theirPartyId" type="id"
      productId" type="id"
      theirProductId" type="id"
      inventoryItemId" type="id"
      glAccountTypeId" type="id"
      glAccountId" type="id-ne"
      organizationPartyId" type="id-ne"
      amount" type="currency-amount"
      currencyUomId" type="id"
      origAmount" type="currency-amount"
      origCurrencyUomId" type="id"
      debitCreditFlag" type="indicator"
      dueDate" type="date"
      groupId" type="id"
      taxId" type="id"
      reconcileStatusId" type="id"
      settlementTermId" type="id"
      isSummary" type="indicator"
      prim-key acctgTransId
      prim-key acctgTransEntrySeqId
      type="one" rel-entity-name="AcctgTransEntryType"> acctgTransEntryTypeId"/>
      type="one" title="Currency" rel-entity-name="Uom">  <!-- title strictly speaking not necessary here but nice for consistency --> currencyUomId" rel-field-name="uomId"/>
      type="one" title="OrigCurrency" rel-entity-name="Uom"> origCurrencyUomId" rel-field-name="uomId"/>
      type="one" rel-entity-name="AcctgTrans"> acctgTransId"/>
      type="one" rel-entity-name="InventoryItem"> inventoryItemId"/>
      type="one" rel-entity-name="Party"> partyId"/>
      type="one" rel-entity-name="RoleType"> roleTypeId"/>
      type="one-nofk" rel-entity-name="PartyRole"> partyId"/> roleTypeId"/>
      type="one" rel-entity-name="GlAccountType"> glAccountTypeId"/>
      type="one" rel-entity-name="GlAccount"> glAccountId"/>
      type="one" rel-entity-name="GlAccountOrganization"> glAccountId"/> organizationPartyId"/>
      type="one" rel-entity-name="StatusItem"> reconcileStatusId" rel-field-name="statusId"/>
      type="one" rel-entity-name="SettlementTerm"> settlementTermId"/>

开放式

GL_JOURNALLINE" primaryKey="GL_JOURNALENTRY_KEY">
      GL_JOURNALLINE_ID" primaryKey="true" required="true" type="VARCHAR" size="32"
      AD_CLIENT_ID" required="true" type="VARCHAR" size="32"
      AD_ORG_ID" required="true" type="VARCHAR" size="32"
      ISACTIVE" required="true" type="CHAR" size="1" <default>Y
      CREATED" required="true" type="TIMESTAMP" size="7" <default>SYSDATE
      CREATEDBY" required="true" type="VARCHAR" size="32"
      UPDATED" required="true" type="TIMESTAMP" size="7" <default>SYSDATE
      UPDATEDBY" required="true" type="VARCHAR" size="32"
      GL_JOURNAL_ID" required="true" type="VARCHAR" size="32"
      LINE" required="true" type="DECIMAL" size="10,0"
      ISGENERATED" required="true" type="CHAR" size="1" <default>N
      DESCRIPTION" type="NVARCHAR" size="255"
      AMTSOURCEDR" required="true" type="DECIMAL" <default>0
      AMTSOURCECR" required="true" type="DECIMAL" <default>0
      C_CURRENCY_ID" required="true" type="VARCHAR" size="32"
      CURRENCYRATETYPE" required="true" type="VARCHAR" size="60"
      CURRENCYRATE" required="true" type="DECIMAL" <default>0
      DATEACCT" type="TIMESTAMP" size="7"
      AMTACCTDR" required="true" type="DECIMAL" <default>0
      AMTACCTCR" required="true" type="DECIMAL" <default>0
      C_UOM_ID" type="VARCHAR" size="32"
      QTY" type="DECIMAL" <default>0
      C_VALIDCOMBINATION_ID" required="true" type="VARCHAR" size="32"
      C_DEBT_PAYMENT_ID" type="VARCHAR" size="32" 
      C_WITHHOLDING_ID" type="VARCHAR" size="32"
      C_TAX_ID" type="VARCHAR" size="32" autoIncrement="false">
      USER1_ID" type="VARCHAR" size="32" autoIncrement="false">
      USER2_ID" type="VARCHAR" size="32" autoIncrement="false">
      C_CAMPAIGN_ID" type="VARCHAR" size="32" autoIncrement="false">
      C_PROJECT_ID" type="VARCHAR" size="32" autoIncrement="false">
      C_ACTIVITY_ID" type="VARCHAR" size="32" autoIncrement="false">
      C_SALESREGION_ID" type="VARCHAR" size="32" autoIncrement="false">
      M_PRODUCT_ID" type="VARCHAR" size="32" autoIncrement="false">
      C_BPARTNER_ID" type="VARCHAR" size="32" autoIncrement="false">
      C_BPARTNER_ID" type="VARCHAR" size="32" autoIncrement="false">
      <foreign-key foreignTable="AD_CLIENT" name="GL_JOURNALLINE_AD_CLIENT">
        <reference local="AD_CLIENT_ID" foreign="AD_CLIENT_ID"/>
      <foreign-key foreignTable="AD_ORG" name="GL_JOURNALLINE_AD_ORG">
        <reference local="AD_ORG_ID" foreign="AD_ORG_ID"/>
      <foreign-key foreignTable="C_ACTIVITY" name="GL_JOURNALLINE_C_ACTIVITY">
        <reference local="C_ACTIVITY_ID" foreign="C_ACTIVITY_ID"/>
      <foreign-key foreignTable="C_BPARTNER" name="GL_JOURNALLINE_C_BPARTNER">
        <reference local="C_BPARTNER_ID" foreign="C_BPARTNER_ID"/>
      <foreign-key foreignTable="C_CAMPAIGN" name="GL_JOURNALLINE_C_CAMPAIGN">
        <reference local="C_CAMPAIGN_ID" foreign="C_CAMPAIGN_ID"/>
      <foreign-key foreignTable="C_CURRENCY" name="GL_JOURNALLINE_C_CURRENCY">
        <reference local="C_CURRENCY_ID" foreign="C_CURRENCY_ID"/>
      <foreign-key foreignTable="C_DEBT_PAYMENT" name="GL_JOURNALLINE_C_DEBT_PAYMENT">
        <reference local="C_DEBT_PAYMENT_ID" foreign="C_DEBT_PAYMENT_ID"/>
      <foreign-key foreignTable="C_PROJECT" name="GL_JOURNALLINE_C_PROJECT">
        <reference local="C_PROJECT_ID" foreign="C_PROJECT_ID"/>
      <foreign-key foreignTable="C_SALESREGION" name="GL_JOURNALLINE_C_SALESREGION">
        <reference local="C_SALESREGION_ID" foreign="C_SALESREGION_ID"/>
      <foreign-key foreignTable="C_TAX" name="GL_JOURNALLINE_C_TAX">
        <reference local="C_TAX_ID" foreign="C_TAX_ID"/>
      <foreign-key foreignTable="C_UOM" name="GL_JOURNALLINE_C_UOM">
        <reference local="C_UOM_ID" foreign="C_UOM_ID"/>
      <foreign-key foreignTable="C_VALIDCOMBINATION" name="GL_JOURNALLINE_C_VALIDCOMBINAT">
        <reference local="C_VALIDCOMBINATION_ID" foreign="C_VALIDCOMBINATION_ID"/>
      <foreign-key foreignTable="C_WITHHOLDING" name="GL_JOURNALLINE_C_WITHHOLDING">
        <reference local="C_WITHHOLDING_ID" foreign="C_WITHHOLDING_ID"/>
      <foreign-key foreignTable="GL_JOURNAL" name="GL_JOURNALLINE_GL_JOURNAL">
        <reference local="GL_JOURNAL_ID" foreign="GL_JOURNAL_ID"/>
      <foreign-key foreignTable="M_PRODUCT" name="GL_JOURNALLINE_M_PRODUCT">
        <reference local="M_PRODUCT_ID" foreign="M_PRODUCT_ID"/>
      <check (C_TAX_ID IS NULL) OR (C_WITHHOLDING_ID IS NULL)]]>
      <check ISACTIVE IN ('Y', 'N')]]>
      <check ISGENERATED IN ('Y', 'N')]]>

邮筒

CREATE TABLE gltrans (
    gltrans_id integer DEFAULT nextval(('"gltrans_gltrans_id_seq"'::text)::regclass) NOT NULL,
    gltrans_exported boolean,
    gltrans_created timestamp with time zone,
    gltrans_date date NOT NULL,
    gltrans_sequence integer,
    gltrans_accnt_id integer NOT NULL,
    gltrans_source text,
    gltrans_docnumber text,
    gltrans_misc_id integer,
    gltrans_amount numeric(20,2) NOT NULL,
    gltrans_notes text,
    gltrans_journalnumber integer,
    gltrans_posted boolean NOT NULL,
    gltrans_doctype text,
    gltrans_rec boolean DEFAULT false NOT NULL,
    gltrans_username text DEFAULT geteffectivextuser() NOT NULL,
    gltrans_deleted boolean DEFAULT false
); 

开瓶器

  _columns = {
        'name': fields.char('Number', size=64, required=True),
        'ref': fields.char('Reference', size=64),
        'period_id': fields.many2one('account.period', 'Period', required=True, states={'posted':[('readonly',True)]}),
        'journal_id': fields.many2one('account.journal', 'Journal', required=True, states={'posted':[('readonly',True)]}),
        'state': fields.selection([('draft','Unposted'), ('posted','Posted')], 'Status', required=True, readonly=True)       
        'line_id': fields.one2many('account.move.line', 'move_id', 'Entries', states={'posted':[('readonly',True)]}),
        'to_check': fields.boolean('To Review', ),
        'partner_id': fields.related('line_id', 'partner_id', type="many2one", relation="res.partner", string="Partner", store=True),
        'amount': fields.function(_amount_compute, string='Amount', digits_compute=dp.get_precision('Account'), type='float', fnct_search=_search_amount),
        'date': fields.date('Date', required=True, states={'posted':[('readonly',True)]}, select=True),
        'narration':fields.text('Internal Note'),
        'company_id': fields.related('journal_id','company_id',type='many2one',relation='res.company',string='Company', store=True, readonly=True),
        'balance': fields.float('balance', digits_compute=dp.get_precision('Account')),
    }

    _defaults = {
        'name': '/',
        'state': 'draft',
        'period_id': _get_period,
        'date': fields.date.context_today,
        'company_id': lambda self, cr, uid, c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.id,
    }

韦伯

CREATE TABLE `gltrans` (
  `counterindex` int(11) NOT NULL AUTO_INCREMENT,
  `type` smallint(6) NOT NULL DEFAULT '0',
  `typeno` bigint(16) NOT NULL DEFAULT '1',
  `chequeno` int(11) NOT NULL DEFAULT '0',
  `trandate` date NOT NULL DEFAULT '0000-00-00',
  `periodno` smallint(6) NOT NULL DEFAULT '0',
  `account` varchar(20) NOT NULL DEFAULT '0',
  `narrative` varchar(200) NOT NULL DEFAULT '',
  `amount` double NOT NULL DEFAULT '0',
  `posted` tinyint(4) NOT NULL DEFAULT '0',
  `jobref` varchar(20) NOT NULL DEFAULT '',
  `tag` tinyint(4) NOT NULL DEFAULT '0',
  PRIMARY KEY (`counterindex`),
  KEY `Account` (`account`),
  KEY `ChequeNo` (`chequeno`),
  KEY `PeriodNo` (`periodno`),
  KEY `Posted` (`posted`),
  KEY `TranDate` (`trandate`),
  KEY `TypeNo` (`typeno`),
  KEY `Type_and_Number` (`type`,`typeno`),
  KEY `JobRef` (`jobref`),
  KEY `tag` (`tag`),
  KEY `tag_2` (`tag`),
  KEY `tag_3` (`tag`),
  KEY `tag_4` (`tag`),
  FOREIGN KEY (`account`) REFERENCES `chartmaster` (`accountcode`),
  FOREIGN KEY (`type`) REFERENCES `systypes` (`typeid`),
  FOREIGN KEY (`periodno`) REFERENCES `periods` (`periodno`)
) 

erpnext


采购订单

于 2013-05-25T21:13:42.673 回答