class LinkListItem(Model): _name = "cms.linklist.item" _fields = { "list_id": fields.Many2One("cms.linklist", "Link List", required=True, on_delete="cascade"), "sequence": fields.Integer("Sequence"), "title": fields.Char("Title", required=True, translate=True), "type": fields.Selection([["menu", "Menu"], ["submenu", "Submenu"]], "Type", required=True), "url": fields.Char("URL", required=True, size=256), "sub_items": fields.One2Many("cms.linklist.item", None, "Sub Items", function="get_sub_items"), } _defaults = { "type": "menu", } _order = "list_id,sequence,id" def get_sub_items(self, ids, context={}): list_ids = [] for obj in self.browse(ids): list_ids.append(obj.list_id.id) list_ids = list(set(list_ids)) sub_items = {} for lst in get_model("cms.linklist").browse(list_ids): parent_id = None for item in lst.items: if item.type == "menu": sub_items[item.id] = [] parent_id = item.id elif item.type == "submenu": sub_items[parent_id].append(item.id) return {id: sub_items[id] for id in ids}
class InlineHelp(Model): _name = "inline.help" _string = "Help Item" _fields = { "action": fields.Char("Action Name", required=True, search=True), "title": fields.Char("Help Title", required=True, search=True), "content": fields.Text("Help Content", required=True, search=True), "hide": fields.Boolean("Hide"), "create_date": fields.DateTime("Date Created"), "modif_date": fields.DateTime("Date Modified"), } _order = "title" _defaults = { "create_date": lambda *a: time.strftime("%Y-%m-%d %H:%M:%S"), "modif_date": lambda *a: time.strftime("%Y-%m-%d %H:%M:%S"), } def create(self, vals, **kw): res = super().create(vals, **kw) static.clear_translations() # XXX: rename this return res def write(self, ids, vals, **kw): super().write(ids, vals, **kw) static.clear_translations() # XXX: rename this def delete(self, ids, **kw): super().delete(ids, **kw) static.clear_translations() # XXX: rename this
class StockJournal(Model): _name = "stock.journal" _string = "Stock Journal" _key = ["name"] _fields = { "name": fields.Char("Name", required=True, search=True), "code": fields.Char("Code", search=True), "sequence_id": fields.Many2One("sequence", "Sequence", multi_company=True), "location_from_id": fields.Many2One("stock.location", "Location From", search=True, multi_company=True), "location_to_id": fields.Many2One("stock.location", "Location To", search=True, multi_company=True), "comments": fields.One2Many("message", "related_id", "Comments"), } _order = "name"
class CustomOption(Model): _name = "product.custom.option" _string = "Custom Option" _key = ["code"] _fields = { "name": fields.Char("Name", required=True, search=True, translate=True), "seq": fields.Char("Sequence", required=True), "code": fields.Char("Code", search=True), "type": fields.Selection([["text", "Text"], ["selection", "Selection"]], "Type", required=True), "required": fields.Boolean("Required"), "description": fields.Text("Description"), "price": fields.Decimal("Price"), "values": fields.One2Many("product.custom.option.value", "cust_opt_id", "Values"), } _defaults = { "type": "text", "seq": '0', }
class ContactCateg(Model): _name = "contact.categ" _string = "Contact Category" _key = ["code"] _name_field = "name" _fields = { "name": fields.Char("Category Name", required=True, search=True), "code": fields.Char("Category Code", search=True), "parent_id": fields.Many2One("contact.categ", "Parent", search=True), "description": fields.Text("Description"), "comments": fields.One2Many("message", "related_id", "Comments"), "full_name": fields.Char("Full Name", function="get_full_name"), } _order = "code" def get_full_name(self, ids, context={}): vals = {} for obj in self.browse(ids): n = obj.name p = obj.parent_id while p: n = p.name + " / " + n p = p.parent_id vals[obj.id] = n return vals
class Website(Model): _name = "website" _string = "Website" _fields = { "name": fields.Char("Website Title"), "parent_categ_id": fields.Many2One("product.categ", "Product Category"), "parent_group_id": fields.Many2One("product.group", "Product Group"), "contact_categ_id": fields.Many2One("contact.categ", "Customer Contact Category"), "user_profile_id": fields.Many2One("profile", "Customer User Profile"), "sale_account_id": fields.Many2One("account.account", "Sales Account"), "sale_tax_id": fields.Many2One("account.tax.rate", "Sales Tax"), "account_receivable_id": fields.Many2One("account.account", "Receivable Account"), "news_categ_id": fields.Many2One("contact.categ", "Newsletter Contact Category"), "target_list_id": fields.Many2One("mkt.target.list", "Newsletter Target List"), "invoice_flag": fields.Boolean("Use same invoice number as sale order number"), "ship_product_id": fields.Many2One("product", "Shipping Product"), "preview_doc_categ_id": fields.Many2One("document.categ", "Preview picture document category"), "invoice_template_id": fields.Many2One("report.template", "Invoice Template"), "payment_slip_template_id": fields.Many2One("report.template", "Payment Slip Template"), "auto_create_account": fields.Boolean("Auto-create customer account after checkout"), "ga_script": fields.Text("Google Analytic script"), "state": fields.Selection([["active", "Active"], ["inactive", "Inactive"]], "Status", required=True), "theme_id": fields.Many2One("theme", "Theme"), "settings": fields.One2Many("website.setting","website_id","Website Settings"), "sale_channel_id": fields.Many2One("sale.channel","Sales Channel"), "bank_method_id": fields.Many2One("payment.method","Bank Transfer",condition=[["type","=","bank"]]), "paypal_method_id": fields.Many2One("payment.method","Paypal",condition=[["type","=","paypal"]]), "paysbuy_method_id": fields.Many2One("payment.method","Paysbuy",condition=[["type","=","paysbuy"]]), "scb_method_id": fields.Many2One("payment.method","SCB Gateway",condition=[["type","=","scb_gateway"]]), "url": fields.Char("Website URL"), } _order="name" _defaults = { "state": "active", }
class Rule(Model): _name = "wkf.rule" _string = "Workflow Rule" _name_field = "description" _fields = { "trigger_model_id": fields.Many2One("model", "Trigger Model", required=True, search=True), "trigger_event": fields.Char("Trigger Event", required=True, search=True), "condition_method": fields.Char("Condition Method"), "condition_args": fields.Text("Condition Arguments"), "action_model_id": fields.Many2One("model", "Action Model", required=True, search=True), "action_method": fields.Char("Action Method", required=True), "action_args": fields.Text("Action Arguments"), "description": fields.Text("Rule Description", search=True), "comments": fields.One2Many("message", "related_id", "Comments"), "state": fields.Selection([["active", "Active"], ["inactive", "Inactive"]], "Status", required=True, search=True), "error": fields.Text("Error Message"), } _order = "trigger_model_id.name,trigger_event,action_model_id.name,action_method" _defaults = { "state": "active", }
class ScheduleLine(Model): _name = "hr.schedule.line" _string = "Schedule Line" def get_time_stop(self, ids, context={}): res = {} for obj in self.browse(ids): datenow = datetime.now().strftime("%Y-%m-%d") time_start = '%s %s' % (datenow, obj.time_start) time_total = obj.time_total or 0.0 if obj.skip_mid: time_total += 1 # 12.00-13.00 seconds = (time_total) * 60 * 60 time_stop = datetime.strptime(time_start, '%Y-%m-%d %H:%S') + timedelta(seconds=seconds) res[obj.id] = time_stop.strftime("%H:%S") return res _fields = { 'schedule_id': fields.Many2One("hr.schedule", "Schedule"), "dow": fields.Selection([["1", "Monday"], ["2", "Tuesday"], ["3", "Wednesday"], ["4", "Thursday"], ["5", "Friday"], ["6", "Saturday"], ["7", "Sunday"]], "Day Of Week"), 'time_start': fields.Char("Time Start"), 'time_stop': fields.Char("Time Stop"), } order = "dow, time_start"
class ProductGroup(Model): _name = "product.group" _string = "Product Group" _key = ["code"] _fields = { "name": fields.Char("Group Name", required=True, search=True), "code": fields.Char("Group Code", search=True), "parent_id": fields.Many2One("product.group", "Parent"), "products": fields.Many2Many("product", "Products"), "filter_products": fields.Many2Many("product", "Products", function="get_filter_products"), "image": fields.File("Image"), "company_id": fields.Many2One("company", "Company"), } _order = "name" def get_filter_products(self, ids, context={}): group_id = ids[0] cond = [["groups.id", "=", group_id], ["is_published", "=", True]] if context.get("product_filter"): cond.append(context["product_filter"]) prod_ids = get_model("product").search(cond) vals = { group_id: prod_ids, } return vals
class PriceType(Model): _name = "price.type" _string = "Price Type" _fields = { "name": fields.Char("Name", required=True), "currency_id": fields.Many2One("currency", "Currency", required=True), "uom_id": fields.Many2One("uom", "UoM", required=True), "price_format": fields.Char("Price format"), "price_format_factor": fields.Decimal("Price format factor", scale=6), } def convert(self, price, from_id, to_id, context={}): #print("PriceType.convert",price,from_id,to_id) pt_from = self.browse(from_id) pt_to = self.browse(to_id) price_qty = get_model("uom").convert(price, pt_to.uom_id.id, pt_from.uom_id.id, context=context) #print("price_qty",price_qty) price_cur = get_model("currency").convert(price_qty, pt_from.currency_id.id, pt_to.currency_id.id, context=context) #print("price_cur",price_cur) return price_cur
class Schedule(Model): _name = "hr.schedule.time" _string = "Schedule Time" def fmt_time(self, time_str): time_str = time_str or "" time_str = time_str.replace(".", ":") if not time_str: time_str = '00:00' return time_str def get_total(self, ids, context={}): res = {} for obj in self.browse(ids): time_start = datetime.strptime(self.fmt_time(obj.time_start), '%H:%S') time_stop = datetime.strptime(self.fmt_time(obj.time_stop), '%H:%S') hrs = (time_stop - time_start).seconds / 60.0 / 60.0 res[obj.id] = hrs return res _fields = { 'schedule_id': fields.Many2One('hr.schedule', "Schedule"), "name": fields.Char("Name", search=True), 'time_start': fields.Char("Time Start", size=5), 'time_stop': fields.Char("Time Stop", size=5), 'time_total': fields.Decimal("Working Time (HRS)", function="get_total"), }
class ProductBrand(Model): _name = "product.brand" _string = "Brand" _fields = { "name": fields.Char("Name", required=True, search=True), "description": fields.Text("Description", search=True), "image": fields.File("Image"), "code": fields.Char("Code"), "parent_id": fields.Many2One("product.brand","Parent Brand"), "sub_brands": fields.One2Many("product.brand","parent_id","Sub Brands"), "products": fields.One2Many("product","brand_id","Products", operator="child_of"), "num_products": fields.Integer("Number of products", function="get_num_products"), "groups": fields.Many2Many("product.brand.group","Group"), } _order = "name" def get_num_products(self, ids, context={}): vals = {} for obj in self.browse(ids): nums = 0 for product in obj.products: if not product.parent_id: nums += 1 vals[obj.id] = nums return vals
class Profile(Model): _name = "profile" _string = "Profile" _key = ["name"] _fields = { "name": fields.Char("Name", required=True, search=True), "code": fields.Char("Short Code"), "perms": fields.One2Many("profile.access", "profile_id", "Model Permissions"), "field_perms": fields.One2Many("field.access", "profile_id", "Field Permissions"), "menu_perms": fields.One2Many("menu.access", "profile_id", "Menu Permissions"), "other_perms": fields.Many2Many("permission", "Other Permissions"), "home_action": fields.Char("Login Action"), "login_company_id": fields.Many2One("company", "Login Company"), "prevent_login": fields.Boolean("Prevent Login"), "comments": fields.One2Many("message", "related_id", "Comments"), "default_model_perms": fields.Selection([["full", "Full Access"], ["readonly","Read-only Access"], ["no", "No Access"]], "Default Model Permissions"), "default_menu_access": fields.Selection([["visible", "Visible"], ["hidden", "Hidden"]], "Default Menu Access"), } _order = "name" _defaults = { "default_model_perms": "full", } def get_data(self, context={}): vals = {} perms = [] for m in get_model("model").search_browse([]): perms.append({ "model_id": [m.id, m.string], }) vals["perms"] = perms return vals def copy(self, ids, context={}): obj = self.browse(ids)[0] vals = { "name": obj.name + " (Copy)", "perms": [], "other_perms": [("set", [p.id for p in obj.other_perms])], "home_action": obj.home_action, } for perm in obj.perms: vals["perms"].append(("create", { "model_id": perm.model_id.id, "perm_read": perm.perm_read, "perm_create": perm.perm_create, "perm_write": perm.perm_write, "perm_delete": perm.perm_delete, "view_all": perm.view_all, "modif_all": perm.modif_all, })) profile_id = get_model("profile").create(vals) return { "next": { "name": "profile", "mode": "form", "active_id": profile_id, }, "flash": "New profile created", }
class customerMessage(Model): _name = "cms.customer.message" _fields = { "name": fields.Char("Name", required=True), "email": fields.Char("Email", required=True), "description": fields.Text("Description", required=True), }
class FaultCode(Model): _name = "fault.code" _string = "Fault Code" _name_field = "code" _fields = { "code": fields.Char("Fault Code", required=True, search=True), "description": fields.Char("Description", search=True), } _order = "code" def name_get(self, ids, context={}): vals = [] for obj in self.browse(ids): name = "%s" % (obj.code) if obj.description: name += " [%s]" % (obj.description) vals.append((obj.id, name)) return vals def name_search(self, name, condition=None, context={}, **kw): cond = [["code", "ilike", "%" + name + "%"]] if condition: cond = [cond, condition] ids1 = self.search(cond) cond = [["description", "ilike", "%" + name + "%"]] if condition: cond = [cond, condition] ids2 = self.search(cond) ids = list(set(ids1 + ids2)) return self.name_get(ids, context=context)
class Page(Model): _name = "cms.page" _string = "Page" _name_field = "title" _fields = { "title": fields.Char("Title", required=True, translate=True, search=True), "code": fields.Char("Code", required=True, search=True), "body": fields.Text("Body", translate=True), "blocks": fields.One2Many("cms.block", "related_id", "Blocks"), "comments": fields.One2Many("message", "related_id", "Comments"), "meta_description": fields.Char("Meta Description"), "meta_keywords": fields.Char("Meta Keywords"), "template": fields.Char("Template"), "state": fields.Selection([["active", "Active"], ["inactive", "Inactive"]], "Status", required=True), } _defaults = { "state": "active", }
class Seller(Model): _name = "seller" _string = "Seller" _fields = { "name": fields.Char("Name", required=True, search=True), "code": fields.Char("Code", search=True), } _order = "name"
class Messenger(Model): _name = "messenger" _string = "Messenger" _fields = { "name": fields.Char("Name", required=True), "code": fields.Char("Code"), } _order = "name"
class SaleChannel(Model): _name = "sale.channel" _string = "Sales Channel" _fields = { "name": fields.Char("Name", required=True, search=True), "code": fields.Char("Code", search=True), "pricelist_id": fields.Many2One("price.list", "Price List"), }
class Report(Model): _name = "report.custom" _name_field = "Custom Report" _fields = { "name": fields.Char("Report Name", required=True), "code": fields.Char("Report Code"), "config": fields.Text("Configuration Data"), }
class TranslationField(Model): _name = "translation.field" _fields = { "model": fields.Char("Model", required=True), "field": fields.Char("Field", required=True), "rec_id": fields.Integer("Record ID", required=True), "lang": fields.Selection([["zh_CN", "Chinese"], ["en_US", "English"], ["my_MM", "Myanmar"], ["th_TH", "Thai"]], "Language", required=True), "translation": fields.Text("Translation"), }
class SmsTemplate(Model): _name = "sms.template" _string = "SMS Template" _name_field = "sender" _fields = { "name": fields.Char("Template Name", required=True, search=True), "phone": fields.Char("Phone Number", required=True, size=256, search=True), "body": fields.Text("Body", search=True), "account_id": fields.Many2One("sms.account", "SMS Account"), } _order = "name" def create_sms(self, ids, data={}, name_id=None, related_id=None, context={}): print("SMSTemplate.create_sms", ids) obj = self.browse(ids)[0] try: phone = render_template(obj.phone or "", data) except: raise Exception("Failed to render 'Phone' in template: %s" % obj.name) try: body = render_template(obj.body or "", data) except: raise Exception("Failed to render 'Body' in template: %s" % obj.name) if obj.related and not related_id: try: related_id = render_template(obj.related or "", data) except: raise Exception( "Failed to render 'Related To' in template: %s" % obj.name) if obj.contact and not name_id: try: name_id = render_template(obj.contact or "", data) except: raise Exception("Failed to render 'Contact' in template: %s" % obj.name) else: name_id = None vals = { "date": time.strftime("%Y-%m-%d %H:%M:%S"), "phone": phone, "body": body, "state": "to_send", "account_id": obj.account_id.id, } print("vals", vals) sms_id = get_model("sms.message").create(vals) return sms_id
class ServiceType(Model): _name = "service.type" _string = "Service Type" _fields = { "name": fields.Char("Name", required=True, search=True), "code": fields.Char("Code", search=True), "description": fields.Text("Description", search=True), "parent_id": fields.Many2One("service.type", "Parent"), } _order = "name"
class Department(Model): _name = "hr.department" _string = "Department" _key = ["name"] _fields = { "name": fields.Char("Name", required=True, search=True), "code": fields.Char("Code"), "comments": fields.One2Many("message", "related_id", "Comments"), } _order = "name"
class FleetSize(Model): _name = "fleet.size" _string = "Fleet Size" _fields = { "code": fields.Char("Code", search=True), "name": fields.Char("Name", required=True, search=True), "description": fields.Text("Description"), "comments": fields.One2Many("message", "related_id", "Comments"), } _order = "code"
class Attribute(Model): _name = "product.attribute" _string = "Attribute" _key = ["code"] _fields = { "name": fields.Char("Attribute Name", required=True, search=True), "code": fields.Char("Attribute Code", required=True, search=True), "options": fields.One2Many("product.attribute.option", "attribute_id", "Options"), } _order="name"
class SaleStage(Model): _name = "sale.stage" _string = "Sales Stage" _key = ["name"] _fields = { "name": fields.Char("Name", required=True, search=True), "sequence": fields.Char("Sequence"), "comments": fields.One2Many("message", "related_id", "Comments"), } _order = "sequence"
class StoreType(Model): _name = "store.type" _string = "Storage Type" _fields = { "name": fields.Char("Name", required=True), "code": fields.Char("Code"), "description": fields.Text("Description"), "comments": fields.One2Many("message", "related_id", "Comments"), } _order = "name"
class Application(Model): _name = "service.application" _string = "Application" _fields = { "name": fields.Char("Name", required=True, search=True), "code": fields.Char("Code", required=True, search=True), "industry_id": fields.Many2One("industry", "Industry", search=True), "description": fields.Text("Description", search=True), } _order = "name"
class CopyDB(Model): _name = "copy_db" _store = False _fields = { "super_password": fields.Char("Super Admin Password", required=True), "dbname": fields.Selection([], "Database Name", required=True), "new_dbname": fields.Char("New Database Name", required=True), } def get_databases(self, context={}): db_list = sorted(database.list_databases()) if config.get("sub_server"): request = context["request"] host = request.host i = host.find(".my.netforce.com") if i == -1: raise Exception("Invalid host") db_name = host[:i].replace("-", "_") db_list = [db_name] elif config.get("database"): db_list = [config.get("database")] return [(x, x) for x in db_list] def copy_db(self, context={}): data = context["data"] if data["super_password"] != config.get("super_password"): raise Exception("Invalid super admin password") dbname = data["dbname"] new_dbname = data["new_dbname"] print("copying db...") # database.close_connections(dbname); db = database.connect("template1") db._db.set_isolation_level(0) db.execute( "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname=%s", dbname) db.execute("CREATE DATABASE %s WITH TEMPLATE %s" % (new_dbname, dbname)) db.close() print("copying files...") fdir1 = os.path.join("static", "db", dbname, "files") if os.path.exists(fdir1): fdir2 = os.path.join("static", "db", new_dbname, "files") if not os.path.exists(fdir2): os.makedirs(fdir2) for f in os.listdir(fdir1): f1 = os.path.join(fdir1, f) f2 = os.path.join(fdir2, f) shutil.copy(f1, f2) return { "next": { "name": "login" }, "flash": "Database copied successfully", }