class LeavePeriod(Model): _name = "hr.leave.period" _string = "Leave Period" _name_field = "date_from" # XXX _fields = { "leave_type_id": fields.Many2One("hr.leave.type", "Leave Type", required=True, search=True), "date_from": fields.Date("From Date", required=True, search=True), "date_to": fields.Date("To Date", required=True, search=True), "max_days": fields.Decimal("Max Days", search=True), } _order = "date_from" def name_search(self, name, condition=[], limit=None, context={}): ids = self.search(condition, limit=limit) return self.name_get(ids, context) def name_get(self, ids, context={}): vals = [] for obj in self.browse(ids): name = "%s - %s" % (obj.date_from, obj.date_to) vals.append((obj.id, name)) return vals def import_get(self, name, context={}): parent_vals = context["parent_vals"] leave_type_id = parent_vals["leave_type_id"] res = name.split(" - ") if len(res) != 2: raise Exception("Invalid leave period format: '%s'" % name) date_from, date_to = res cond = [["leave_type_id", "=", leave_type_id], ["date_from", "=", date_from], ["date_to", "=", date_to]] res = self.search(cond) if not res: raise Exception("Leave period not found") return res[0]
class ProductionPeriod(Model): _name = "production.period" _string = "Production Period" _name_field = "number" _fields = { "number": fields.Char("Number", required=True, search=True), "date_from": fields.Date("Date From", required=True), "date_to": fields.Date("Date To", required=True), "production_orders": fields.One2Many("production.order", "period_id", "Production Orders"), "costs": fields.One2Many("production.period.cost", "period_id", "Period Costs"), "amount_total": fields.Decimal("Period Actual Total", function="get_total", function_multi=True), "alloc_total": fields.Decimal("Production Order Total", function="get_total", function_multi=True), } def update_period_costs(self, ids, context={}): obj = self.browse(ids)[0] cost_prod_ids = [] for cost in get_model("production.cost").search_browse( [["order_id.period_id", "=", obj.id]]): prod_id = cost.product_id.id cost_prod_ids.append(prod_id) cost_prod_ids = list(set(cost_prod_ids)) cur_prod_ids = [c.product_id.id for c in obj.costs] new_prod_ids = [ prod_id for prod_id in cost_prod_ids if prod_id not in cur_prod_ids ] for prod_id in new_prod_ids: vals = { "period_id": obj.id, "product_id": prod_id, "amount": 0, } get_model("production.period.cost").create(vals) def get_total(self, ids, context={}): vals = {} for obj in self.browse(ids): amt = 0 alloc = 0 for cost in obj.costs: amt += cost.amount or 0 alloc += cost.alloc_amount or 0 vals[obj.id] = { "amount_total": amt, "alloc_total": alloc, } return vals
class FixedAssetPeriod(Model): _name = "account.fixed.asset.period" _fields = { "asset_id": fields.Many2One("account.fixed.asset", "Fixed Asset", required=True, on_delete="cascade"), "date_from": fields.Date("From", required=True), "date_to": fields.Date("To", required=True), "amount": fields.Decimal("Depr. Amount", required=True), "move_id": fields.Many2One("account.move", "Journal Entry", on_delete="cascade"), } _order = "asset_id,date_to"
class SaleTarget(Model): _name = "sale.target" _string = "Sales Target" _key = ["user_id"] _fields = { "user_id": fields.Many2One("base.user", "Salesman", search=True), "prod_categ_id": fields.Many2One("product.categ", "Product Category", search=True), "date_from": fields.Date("From Date", required=True), "date_to": fields.Date("To Date", required=True, search=True), "amount_target": fields.Decimal("Target Amount"), "amount_actual": fields.Decimal("Actual Amount", function="get_amount", function_multi=True), "amount_expected": fields.Decimal("Expected Amount", function="get_amount", function_multi=True), "qty_target": fields.Decimal("Target Qty"), "qty_actual": fields.Decimal("Actual Qty", function="get_amount", function_multi=True), "qty_expected": fields.Decimal("Expected Qty", function="get_amount", function_multi=True), "comments": fields.One2Many("message", "related_id", "Comments"), } _order = "date_from,user_id,prod_categ_id" _defaults = { "date_from": lambda *a: date.today().strftime("%Y-%m-01"), "date_to": lambda *a: (date.today() + relativedelta(day=31)).strftime("%Y-%m-%d"), } def get_amount(self, ids, context={}): all_vals = {} db = database.get_connection() for obj in self.browse(ids): q = "SELECT SUM(opp.amount) AS amount,SUM(opp.qty) AS qty FROM sale_opportunity opp LEFT JOIN product prod ON prod.id=opp.product_id WHERE opp.state='won' AND opp.date_close>=%s AND opp.date_close<=%s" a = [obj.date_from, obj.date_to] if obj.user_id: q += " AND opp.user_id=%s" a.append(obj.user_id.id) if obj.prod_categ_id: q += " AND prod.categ_id=%s" a.append(obj.prod_categ_id.id) res_won = db.get(q, *a) q = "SELECT SUM(opp.amount*opp.probability/100) AS amount,SUM(opp.qty*opp.probability/100) AS qty FROM sale_opportunity opp LEFT JOIN product prod ON prod.id=opp.product_id WHERE opp.state='open' AND opp.date_close>=%s AND opp.date_close<=%s" a = [obj.date_from, obj.date_to] if obj.user_id: q += " AND opp.user_id=%s" a.append(obj.user_id.id) if obj.prod_categ_id: q += " AND prod.categ_id=%s" a.append(obj.prod_categ_id.id) res_open = db.get(q, *a) vals = { "amount_actual": res_won.amount or 0, "amount_expected": res_open.amount or 0, "qty_actual": res_won.qty or 0, "qty_expected": res_open.qty or 0, } all_vals[obj.id] = vals return all_vals
class ReportTaxSum(Model): _name = "report.tax.sum" _transient = True _fields = { "date_from": fields.Date("From"), "date_to": fields.Date("To"), "by_rate": fields.Boolean("Show by Tax Rate"), "by_comp": fields.Boolean("Show by Tax Component"), } _defaults = { "date_from": lambda *a: date.today().strftime("%Y-%m-01"), "date_to": lambda *a: (date.today() + relativedelta(day=31)).strftime("%Y-%m-%d"), "by_comp": True, } def get_report_data(self, ids, context={}): company_id = get_active_company() company_ids = get_model("company").search( [["id", "child_of", company_id]]) comp = get_model("company").browse(company_id) if ids: params = self.read(ids, load_m2o=False)[0] else: params = self.default_get(load_m2o=False, context=context) settings = get_model("settings").browse(1) date_from = params.get("date_from") if not date_from: date_from = date.today().strftime("%Y-%m-01") date_to = params.get("date_to") if not date_to: date_to = (date.today() + relativedelta(day=31)).strftime("%Y-%m-%d") data = { "company_name": comp.name, "date_from": date_from, "date_to": date_to, "by_rate": params.get("by_rate"), "by_comp": params.get("by_comp"), } db = database.get_connection() if params.get("by_comp"): res = db.query( "SELECT c.id AS comp_id,c.name AS comp_name,c.rate AS comp_rate,r.name AS rate_name,SUM(l.credit-l.debit) AS tax_total,SUM(l.tax_base*sign(l.credit-l.debit)) AS base_total FROM account_move_line l,account_move m,account_tax_component c,account_tax_rate r WHERE m.id=l.move_id AND m.state='posted' AND m.date>=%s AND m.date<=%s AND c.id=l.tax_comp_id AND r.id=c.tax_rate_id AND m.company_id IN %s GROUP BY comp_id,comp_name,comp_rate,rate_name ORDER BY comp_name,rate_name", date_from, date_to, tuple(company_ids)) data["comp_taxes"] = [dict(r) for r in res] if params.get("by_rate"): res = db.query( "SELECT c.id AS comp_id,c.name AS comp_name,c.rate AS comp_rate,r.name AS rate_name,SUM(l.credit-l.debit) AS tax_total,SUM(l.tax_base*sign(l.credit-l.debit)) AS base_total FROM account_move_line l,account_move m,account_tax_component c,account_tax_rate r WHERE m.id=l.move_id AND m.state='posted' AND m.date>=%s AND m.date<=%s AND c.id=l.tax_comp_id AND r.id=c.tax_rate_id AND m.company_id IN %s GROUP BY comp_id,comp_name,comp_rate,rate_name ORDER BY rate_name,comp_name", date_from, date_to, tuple(company_ids)) data["rate_taxes"] = [dict(r) for r in res] return data
class ReportSaleProduct(Model): _name = "report.sale.product" _transient = True _fields = { "date_from": fields.Date("From", required=True), "date_to": fields.Date("To", required=True), } _defaults = { "date_from": lambda *a: date.today().strftime("%Y-%m-01"), "date_to": lambda *a: (date.today() + relativedelta(day=31)).strftime("%Y-%m-%d"), } def get_report_data(self, ids, context={}): if ids: params = self.read(ids, load_m2o=False)[0] else: params = self.default_get(load_m2o=False, context=context) company_id = get_active_company() comp = get_model("company").browse(company_id) settings = get_model("settings").browse(1) date_from = params.get("date_from") date_to = params.get("date_to") if not date_from: date_from = date.today().strftime("%Y-%m-01") if not date_to: date_to = (date.today() + relativedelta(day=31)).strftime("%Y-%m-%d") data = { "company_name": comp.name, "date_from": date_from, "date_to": date_to, "total_qty": 0, "total_amount": 0, } db = get_connection() res = db.query( "SELECT l.product_id,p.name AS product_name,p.sale_price AS product_price,SUM(l.amount) AS amount,SUM(l.qty) AS qty FROM account_invoice_line l,account_invoice i,product p WHERE i.id=l.invoice_id AND p.id=l.product_id AND i.date>=%s AND i.date<=%s GROUP BY l.product_id,p.name,p.sale_price ORDER BY p.name", date_from, date_to) lines = [] for r in res: line = r line["avg_price"] = line["amount"] / line["qty"] if line[ "qty"] else None lines.append(line) data["total_qty"] += line["qty"] data["total_amount"] += line["amount"] data["lines"] = lines data["total_avg_price"] = data["total_amount"] / data[ "total_qty"] if data["total_qty"] else None pprint(data) return data
class ConvSaleInvoice(Model): _name = "conv.sale.invoice" _transient = True _fields = { "conv_id": fields.Many2One("conv.bal", "Conversion", required=True), "number": fields.Char("Number", required=True), "ref": fields.Char("Reference"), "contact_id": fields.Many2One("contact", "Contact", required=True, on_delete="cascade"), "date": fields.Date("Date", required=True), "due_date": fields.Date("Due Date", required=True), "amount_due": fields.Decimal("Amount Due", required=True), "move_line_id": fields.Many2One("account.move.line", "Move Line"), "account_id": fields.Many2One("account.account", "Account", required=True), "amount_cur": fields.Decimal("Currency Amt"), }
class Budget(Model): _name = "account.budget" _string = "Budget" _key = ["name"] _fields = { "name": fields.Char("Name", required=True, search=True), "date_from": fields.Date("From Date"), "date_to": fields.Date("To Date", required=True, search=True), "lines": fields.One2Many("account.budget.line", "budget_id", "Budget Items"), } _order = "name"
class AccountReconcileVATLine(Model): _name = "account.reconcile.vat.line" _name_field = "rec_id" _fields = { "rec_id": fields.Many2One("account.reconcile.vat", "Reconcile ID", required=True, on_delete="cascade"), "tax_date": fields.Date("Tax Date"), "related_id": fields.Reference( [["account.invoice", "Invoice"], ["account.payment", "Payment"], ["account.move", "Move"]], "Related To", required=True), "tax_no": fields.Char("Tax No."), "contact_id": fields.Many2One("contact", "Contact", required=True), "tax_base": fields.Decimal("Tax Base", required=True), "tax_amount": fields.Decimal("Tax Amount", required=True), "move_line_id": fields.Many2One("account.move.line", "Move Line ID", required=True), #Use To Reconcile } _order = "tax_date desc"
class FixedAssetDispose(Model): _name = "account.fixed.asset.dispose" _fields = { "asset_id": fields.Many2One("account.fixed.asset", "Asset", readonly=True), "date": fields.Date("Date", required=True), "loss_acc_id": fields.Many2One("account.account", "Loss Account", required=True), } _defaults = { "date": lambda *a: time.strftime("%Y-%m-%d"), } def dispose(self, ids, context={}): obj = self.browse(ids)[0] res = get_model("account.journal").search([["type", "=", "general"]]) if not res: raise Exception("General journal not found") journal_id = res[0] asset = obj.asset_id desc = "Dispose fixed asset [%s] %s" % (asset.number, asset.name) move_vals = { "journal_id": journal_id, "date": obj.date, "narration": desc, } lines = [] amt = -asset.price_purchase line_vals = { "description": desc, "account_id": asset.fixed_asset_account_id.id, "debit": amt > 0 and amt or 0, "credit": amt < 0 and -amt or 0, } lines.append(line_vals) amt = asset.price_purchase - asset.book_val line_vals = { "description": desc, "account_id": asset.accum_dep_account_id.id, "debit": amt > 0 and amt or 0, "credit": amt < 0 and -amt or 0, } lines.append(line_vals) amt = asset.book_val line_vals = { "description": desc, "account_id": obj.loss_acc_id.id, "debit": amt > 0 and amt or 0, "credit": amt < 0 and -amt or 0, } lines.append(line_vals) move_vals["lines"] = [("create", v) for v in lines] move_id = get_model("account.move").create(move_vals) get_model("account.move").post([move_id]) asset.write({"state": "sold", "date_dispose": obj.date}) return { "next": { "name": "fixed_asset", "mode": "form", "active_id": asset.id, } }
class BatchImportSaleInvoice(Model): _name = "batch.import.sale.invoice" _fields = { "import_id": fields.Many2One("batch.import", "Import", required=True, on_delete="cascade"), "date": fields.Date("Date", required=True), "number": fields.Text("Invoice No."), "contact": fields.Char("Customer Name"), "description": fields.Text("Description"), "amount": fields.Decimal("Amount"), "account_id": fields.Many2One("account.account", "Income Account"), "tax_id": fields.Many2One("account.tax.rate", "Tax Rate"), "invoice_id": fields.Many2One("account.invoice", "Invoice"), }
class EmailReject(Model): _name = "email.reject" _string = "Reject Email" _fields = { "email": fields.Char("Email", required=True, search=True), "reason": fields.Selection([["bounced", "Bounced"], ["rejected", "Rejected"], ["unsubscribed", "Unsubscribed"], ["complained", "Complained"], ["other", "Other"]], "Reason", search=True), "details": fields.Text("Details"), "date": fields.Date("Date Created", required=True, search=True), } _order = "date desc" _defaults = { "date": time.strftime("%Y-%m-%d %H:%M:%S"), } def add_to_black_list(self, email, reason): res = self.search([["email", "=", email]]) if res: return vals = { "email": email, "reason": reason, } self.create(vals)
class Depreciation(Model): _name = "account.fixed.asset.depreciation" _string = "Depreciation" _fields = { "date_to": fields.Date("To Date", required=True), } _transient = True def get_date_to(self, ids, context={}): month = int(datetime.now().strftime("%m")) year = int(datetime.now().strftime("%Y")) day = calendar.monthrange(year, month)[1] last_date = "%s-%s-%s" % (year, month, day) return last_date _defaults = { "date_to": lambda *a: (date.today() + relativedelta(day=31)).strftime("%Y-%m-%d"), } def update(self, ids, context): obj = self.browse(ids)[0] asset_ids = get_model("account.fixed.asset").search( [["state", "=", "registered"]]) get_model("account.fixed.asset").depreciate(asset_ids, obj.date_to) return { "next": { "name": "fixed_asset", "mode": "list", }, "flash": "All registered assets are depreciated to %s" % obj.date_to, }
class StockOrderLine(Model): _name = "stock.order.line" _fields = { "order_id": fields.Many2One("stock.order", "Order", required=True, on_delete="cascade"), "product_id": fields.Many2One("product", "Product", required=True), "qty": fields.Decimal("Order Qty", required=True), "uom_id": fields.Many2One("uom", "Order UoM", required=True), "date": fields.Date("Order Date", required=True), "supply_method": fields.Selection( [["purchase", "Purchase"], ["production", "Production"]], "Supply Method", function="_get_related", function_context={"path": "product_id.supply_method"}), "supplier_id": fields.Many2One("contact", "Supplier", function="get_supplier"), } def get_supplier(self, ids, context={}): vals = {} for obj in self.browse(ids): vals[obj.id] = obj.product_id.suppliers[ 0].supplier_id.id if obj.product_id.suppliers else None return vals
class Target(Model): _name = "mkt.target" _string = "Target" _name_field = "last_name" _fields = { "list_id": fields.Many2One("mkt.target.list", "Target List", required=True, on_delete="cascade"), "date": fields.Date("Date Created", required=True, search=True), "first_name": fields.Char("First Name", search=True), "last_name": fields.Char("Last Name", search=True), "company": fields.Char("Company", size=256, search=True), "email": fields.Char("Email", search=True), "street": fields.Char("Street"), "city": fields.Char("City"), "province_id": fields.Many2One("province", "Province", search=True), "zip": fields.Char("Zip"), "country_id": fields.Many2One("country", "Country", search=True), "phone": fields.Char("Phone"), "fax": fields.Char("Fax"), "mobile": fields.Char("Mobile"), "website": fields.Char("Website"), "birthday": fields.Date("Birthday"), "target_life": fields.Integer("Target Life (days)", function="get_life"), "comments": fields.One2Many("message", "related_id", "Comments"), "email_status": fields.Selection([["error_syntax", "Syntax Error"], ["error_dns", "DNS Error"], ["error_smtp", "SMTP Error"], ["verified", "Verified"]], "Email Status", search=True, readonly=True), "email_error": fields.Text("Email Error Details", readonly=True), } _order = "date desc" _defaults = { "date": lambda *a: time.strftime("%Y-%m-%d"), } def name_get(self, ids, context={}): vals = [] for obj in self.browse(ids): if obj.first_name: name = obj.first_name + " " + obj.last_name else: name = obj.last_name vals.append((obj.id, name)) return vals def get_life(self, ids, context={}): vals = {} for obj in self.browse(ids): vals[obj.id] = (datetime.today() - datetime.strptime(obj.date, "%Y-%m-%d")).days if obj.date else None return vals
class ConvPurchInvoice(Model): _name = "conv.purch.invoice" _transient = True _fields = { "conv_id": fields.Many2One("conv.bal", "Conversion", required=True), "number": fields.Char("Number", required=True), "ref": fields.Char("Reference"), "contact_id": fields.Many2One("contact", "Contact", required=True, on_delete="cascade"), "date": fields.Date("Date", required=True), "due_date": fields.Date("Due Date", required=True), "amount_due": fields.Decimal("Amount Due", required=True), "move_line_id": fields.Many2One("account.move.line", "Move Line"), "account_id": fields.Many2One("account.account", "Account", required=True), "amount_cur": fields.Decimal("Currency Amt"), "track_id": fields.Many2One("account.track.categ", "Track-1", condition=[["type", "=", "1"]]), "track2_id": fields.Many2One("account.track.categ", "Track-2", condition=[["type", "=", "2"]]), }
class ReportBankSum(Model): _name = "report.bank.sum" _store = False _fields = { "date_from": fields.Date("From"), "date_to": fields.Date("To"), } _defaults = { "date_from": lambda *a: date.today().strftime("%Y-%m-01"), "date_to": lambda *a: (date.today() + relativedelta(day=31)).strftime("%Y-%m-%d"), } def get_data(self, context={}): data = { "company_name": context["company_name"], } return data
class CreditAlloc(Model): _name = "account.credit.alloc" _fields = { "invoice_id": fields.Many2One("account.invoice", "Invoice", required=True, on_delete="cascade"), "credit_id": fields.Many2One("account.invoice", "Credit Note", on_delete="cascade"), "credit_move_id": fields.Many2One("account.move", "Credit Journal Entry", on_delete="cascade"), "credit_type": fields.Char("Credit Type", function="_get_related", function_context={"path": "credit_id.inv_type"}), "amount": fields.Decimal("Amount"), "move_id": fields.Many2One("account.move", "Journal Entry"), "date": fields.Date("Date", required=True), } _defaults = { "date": lambda *a: time.strftime("%Y-%m-%d"), } def create(self, vals, **kw): new_id = super().create(vals, **kw) inv_ids = [] inv_id = vals.get("invoice_id") if inv_id: inv_ids.append(inv_id) cred_id = vals.get("credit_id") if cred_id: inv_ids.append(cred_id) if inv_ids: get_model("account.invoice").function_store(inv_ids) return new_id def delete(self, ids, **kw): inv_ids = [] for obj in self.browse(ids): if obj.invoice_id: inv_ids.append(obj.invoice_id.id) if obj.credit_ids: inv_ids.append(obj.credit_id.id) if obj.move_id: obj.move_id.void() obj.move_id.delete() super().delete(ids, **kw) if inv_ids: get_model("account.invoice").function_store(inv_ids)
class CreditWizardLine(Model): _name = "account.credit.wizard.line" _transient = True _fields = { "wiz_id": fields.Many2One("account.credit.wizard", "Wizard", required=True, on_delete="cascade"), "move_line_id": fields.Many2One("account.move.line", "Account Entry", required=True, readonly=True, on_delete="cascade"), "move_id": fields.Many2One("account.move", "Journal Entry", required=True, readonly=True, on_delete="cascade"), "date": fields.Date("Date", readonly=True), "account_id": fields.Many2One("account.account", "Account", required=True, readonly=True, on_delete="cascade"), "amount_credit_remain": fields.Decimal("Outstanding Credit", readonly=True), "amount": fields.Decimal("Amount"), }
class BookstoreCustomer(Model): _name = "bookstore.customer" _fields = { "name": fields.Char("Name", required=True, size=256, search=True), "age": fields.Integer("Age", function="get_age"), "gender": fields.Selection([("male", "Male"), ("female", "Female")], "Gender", required=True), "job": fields.Char("Job"), "birth_date": fields.Date("Birth Date"), "num_of_book_burrowed": fields.Integer("Books Burrowed", function="get_num_of_book_burrowed"), "myfield": fields.Char("blabla"), "sijan_field": fields.Integer("Int"), } _defaults = { "birth_date": lambda *a: datetime.now().strftime("%Y-%m-%d"), } def get_age(self, ids, context={}): vals = {} for obj in self.browse(ids): date_string = obj.birth_date if date_string: date_obj = datetime.strptime(date_string, "%Y-%m-%d") today_obj = datetime.now() age = today_obj.year - date_obj.year vals[obj.id] = age else: vals[obj.id] = 0 return vals def get_num_of_book_burrowed(self, ids, context={}): books = {} for obj in self.browse(ids): num = 0 burrow_ids = get_model("bookstore.burrow").search( [["customer", "=", obj.id]]) for j in burrow_ids: burrow = get_model("bookstore.burrow").browse(j) for line in burrow.lines: num += line.qty books[obj.id] = num return books
class DocumentTmpl(Model): _name = "document.tmpl" _string = "Document Template" _fields = { "file": fields.File("File"), "categ_id": fields.Many2One("document.categ", "Category", required=True, search=True), "description": fields.Text("Description", search=True), "date": fields.Date("Date", required=True, search=True), "attachments": fields.One2Many("attach", "related_id", "Attachments"), "comments": fields.One2Many("message", "related_id", "Comments"), } _defaults = { "date": lambda *a: time.strftime("%Y-%m-%d"), }
class TaskList(Model): _name = "task.list" _string = "Task List" _fields = { "name": fields.Char("Name", required=True), "date_created": fields.Date("Date Created", required=True), "project_id": fields.Many2One("project", "Project"), "milestone_id": fields.Many2One("project.milestone", "Milestone"), "tasks": fields.One2Many("task", "task_list_id", "Tasks"), } _order = "date_created desc,id desc" _defaults = { "date_created": lambda *a: time.strftime("%Y-%m-%d"), }
class Reminder(Model): _name = "reminder" _string = "Reminder" _fields = { "scheduled_date": fields.Date("Scheduled Date", required=True), "doc_id": fields.Many2One("document", "Document", required=True, on_delete="cascade"), "user_id": fields.Many2One("base.user", "To User", required=True), "subject": fields.Char("Subject", required=True), "body": fields.Text("Body"), "state": fields.Selection([["pending", "Pending"], ["sent", "Sent"]], "Status", required=True), } _order = "scheduled_date,id" _defaults = { "scheduled_date": lambda *a: time.strftime("%Y-%m-%d"), "state": "pending", } def send_email(self, ids, context={}): for obj in self.browse(ids): to_addr = obj.user_id.email if not to_addr: continue vals = { "state": "to_send", "from_addr": "*****@*****.**", "to_addrs": to_addr, "subject": obj.subject, "body": obj.body, } get_model("email.message").create(vals) obj.write({"state": "sent"}) def send_reminders(self): t = time.strftime("%Y-%m-%d") ids = self.search([["scheduled_date", "<=", t], ["state", "=", "pending"]]) self.send_email(ids)
class Operation(Model): _name = "mrp.operation" _fields = { "order_id": fields.Many2One("production.order", "Order", required=True, on_delete="cascade"), "date": fields.Date("Date", required=True), "workcenter_id": fields.Many2One("workcenter", "Workcenter", required=True), "hours": fields.Decimal("Hours", required=True), }
class ReportExpenseContact(Model): _name = "report.expense.contact" _store = False _fields = { "date": fields.Date("Date"), } _defaults = { "date": lambda *a: date.today().strftime("%Y-%m-01"), } def get_data(self, context={}): data = { "company_name": context["company_name"], } return data
class Holiday(Model): _name = "hr.holiday" _string = "Holiday" _fields = { "name": fields.Char("Name", search=True), "date": fields.Date("Date", required=True, search=True), "description": fields.Text("Description"), "comments": fields.One2Many("message", "related_id", "Comments"), 'generic': fields.Boolean("Generic"), } _defaults = { "date": lambda *a: time.strftime("%Y-%m-%d"), "comday": False, 'generic': False, } _order = "date" _sql_constraints = [ ("hr_holiday_date_uniq", "unique (date)", "Date should be unique"), ] def get_holidays(self, context={}): date_from = context.get('start_date', time.strftime(FMT_DAY)) date_to = context.get('end_date', time.strftime(FMT_DAY)) cond = [ ['date', '>=', date_from], ['date', '<=', date_to], ] res = set() for r in self.search_read(cond, ['date']): res.update({r['date']}) yearnow, month, date = time.strftime(FMT_DAY).split("-") cond = [['generic', '=', True]] for r in self.search_read(cond, ['date']): y, m, d = r['date'].split("-") date = '-'.join([yearnow, m, d]) res.update({date}) return list(res) def is_holiday(self,ds): d=datetime.strptime(ds,"%Y-%m-%d") w=d.weekday() if w==5 or w==6: return True res=self.search([["date","=",ds]]) if res: return True return False
class TrackEntry(Model): _name = "account.track.entry" _string = "Tracking Entries" _fields = { "track_id": fields.Many2One("account.track.categ", "Tracking Category",required=True,on_delete="cascade",search=True), "date": fields.Date("Date",required=True,search=True), "amount": fields.Decimal("Amount",required=True), "product_id": fields.Many2One("product","Product",search=True), "description": fields.Text("Description"), "qty": fields.Decimal("Qty"), "uom_id": fields.Many2One("uom","UoM"), "unit_price": fields.Decimal("Unit Price"), "related_id": fields.Reference([["account.invoice","Invoice"],["stock.picking","Stock Picking"],["work.time","Work Time"],["hr.expense","Expense Claim"]],"Related To"), "move_id": fields.Many2One("account.move","Journal Entry",search=True), } _order = "date desc,id desc" _defaults={ "date": lambda *a: time.strftime("%Y-%m-%d"), } def onchange_product(self,context={}): data=context.get("data",{}) print("#"*80) print("ID",data.get("id")) prod_id=data["product_id"] if not prod_id: return prod=get_model("product").browse(prod_id) price=prod.cost_price if prod.cost_method == "standard" else prod.landed_cost if not price: raise Exception("Missing Cost Price or Landed Cost") track_id=data["track_id"] track=get_model("account.track.categ").browse(track_id) if track.currency_id: settings=get_model("settings").browse(1) price=get_model("currency").convert(price,settings.currency_id.id,track.currency_id.id) data["unit_price"]=-price data["qty"]=1 data["uom_id"]=prod.uom_id.id data["amount"]=data["unit_price"] return data def update_amount(self,context={}): data=context.get("data",{}) unit_price=data.get("unit_price",0) qty=data.get("qty",0) data["amount"]=unit_price*qty return data
class InvoiceRefund(Model): _name = "invoice.refund" _transient = True _fields = { "amount": fields.Decimal("Amount", required=True), "date": fields.Date("Date", required=True), "account_id": fields.Many2One("account.account", "Account", required=True, condition=[["type", "in", ["bank","cash","cheque"]]], on_delete="cascade"), "ref": fields.Char("Ref"), "invoice_id": fields.Many2One("account.invoice", "Invoice", required=True, on_delete="cascade"), } def _get_invoice(self, context={}): return context["parent_id"] _defaults = { "invoice_id": _get_invoice, } def add_refund(self, ids, context={}): obj = self.browse(ids[0]) inv = obj.invoice_id assert inv.inv_type in ("credit", "prepay", "overpay") if obj.amount > inv.amount_credit_remain: raise Exception("Amount refunded exceeds the remaining credit") vals = { "type": inv.type, "pay_type": "invoice", "contact_id": inv.contact_id.id, "date": obj.date, "ref": obj.ref, "account_id": obj.account_id.id, "currency_id": inv.currency_id.id, "lines": [("create", { "type": "invoice", "invoice_id": inv.id, "account_id": inv.account_id.id, "amount": obj.amount, })], } pmt_id = get_model("account.payment").create(vals, context={"type": vals["type"]}) get_model("account.payment").post([pmt_id]) return { "next": { "name": "view_invoice", "active_id": inv.id, } }
class AutoReconcile(Model): _name = "auto.reconcile" _transient = True _fields = { "account_id": fields.Many2One("account.account", "Account"), "contact_id": fields.Many2One("contact", "Contact"), "to_date": fields.Date("To Date"), } def do_reconcile(self, ids, context={}): obj = self.browse(ids)[0] account_id = obj.account_id.id cond = [["account_id", "=", account_id]] if obj.contact_id: cond.append(["contact_id", "=", obj.contact_id.id]) if obj.to_date: cond.append(["move_date", "<=", obj.to_date]) num_rec = 0 unrec = {} for line in get_model("account.move.line").search_browse( cond, order="move_id.date,id"): if not line.contact_id: continue if line.reconcile_id and line.reconcile_id.balance < 0: # TODO: speed continue amt = line.debit - line.credit key2 = "%d,%.2f" % (line.contact_id.id, -amt) line2_ids = unrec.get(key2) if line2_ids: line2_id = line2_ids.pop(0) if not line2_ids: del unrec[key2] rec_id = get_model("account.reconcile").create({}) get_model("account.move.line").write([line.id, line2_id], {"reconcile_id": rec_id}) num_rec += 2 else: key = "%d,%.2f" % (line.contact_id.id, amt) unrec.setdefault(key, []).append(line.id) return { "next": { "name": "account_reconcile", }, "flash": "%d transactions reconciled" % num_rec, }
class BlogPost(Model): _name = "cms.blog.post" _string = "Blog Post" _name_field = "title" _fields = { "blog_id": fields.Many2One("cms.blog", "Blog", required=True, on_delete="cascade"), "date": fields.Date("Date", required=True), "title": fields.Char("Title", required=True, translate=True), "body": fields.Text("Body", translate=True), "blocks": fields.One2Many("cms.block", "related_id", "Blocks"), "meta_description": fields.Char("Meta Description"), "meta_keywords": fields.Char("Meta Keywords"), "comments": fields.One2Many("message", "related_id", "Comments"), } _defaults = { "date": lambda *a: time.strftime("%Y-%m-%d"), } _order = "date desc"