Beispiel #1
0
 def export_static_files(self, ids, context={}):
     obj = self.browse(ids)[0]
     theme = obj.name
     dbname = get_active_db()
     if obj.file:
         zip_path = utils.get_file_path(obj.file)
         zf = zipfile.ZipFile(zip_path)
         for n in zf.namelist():
             if not n.startswith("static/"):
                 continue
             if n[-1] == "/":
                 continue
             n2 = n[7:]
             if n2.find("..") != -1:
                 continue
             data = zf.read(n)
             f_path = "static/db/" + dbname + "/themes/" + theme + "/" + n2
             dir_path = os.path.dirname(f_path)
             if not os.path.exists(dir_path):
                 os.makedirs(dir_path)
             print("export file", f_path)
             open(f_path, "wb").write(data)
     else:
         export_module_file_all("themes/" + theme + "/static",
                                "static/db/" + dbname + "/themes/" + theme)
Beispiel #2
0
 def import_data(self, ids, context={}):
     obj = self.browse(ids)[0]
     if obj.import_type == 'auto':
         obj.import_auto()
     else:
         if not obj.file:
             raise Exception("File not found")
         if obj.file.split(".")[-1] != 'csv':
             raise Exception("Wrong File")
         fpath = get_file_path(obj.file)
         data = open(fpath, "r").read().split("\n")
         att_ids = []
         records = {}
         for row in data:
             lines = row.split(",")
             if not lines:
                 continue
             size = len(lines)
             if size < 2:
                 continue
             if size > 2:
                 raise Exception("Wrong File")
             att_id = lines[0]
             att_date = lines[1]
             if not records.get(att_id):
                 records[att_id] = []
             records[att_id].append(att_date)
             continue
             # TODO Check format date
             if att_id not in att_ids:
                 att_ids.append(att_id)
         # self.set_att(ids,att_ids,context=context)
         emps = {
             emp['attendance_id']: emp['id']
             for emp in get_model("hr.employee").search_read(
                 [], ['attendance_id'])
         }
         att = get_model("hr.attendance")
         at_ids = att.search([])
         # XXX testing
         att.delete(at_ids)
         for att_id, lines in records.items():
             att_id = int(att_id)
             date_list = []
             for line in lines:
                 datetime = line
                 date = datetime.split(" ")[0]
                 action = 'sign_in'
                 if date in date_list:
                     action = 'sign_out'
                     # FIXME find the last record and overwrite time
                 date_list.append(date)
                 att.create({
                     'employee_id': emps[att_id],
                     'action': action,
                     'time': datetime,
                 })
         print("Done!")
Beispiel #3
0
 def delete(self, ids, **kw):
     files = []
     for obj in self.browse(ids):
         if obj.file:
             files.append(obj.file)
     super().delete(ids, **kw)
     for f in files:
         path = utils.get_file_path(f)
         os.remove(path)
Beispiel #4
0
 def delete(self, ids, **kw):
     files = []
     for obj in self.browse(ids):
         if obj.file:
             files.append(obj.file)
     super().delete(ids, **kw)
     for f in files:
         path = utils.get_file_path(f)
         os.remove(path)
Beispiel #5
0
 def import_data(self, ids, context={}):
     obj = self.browse(ids)[0]
     if obj.import_type == 'auto':
         obj.import_auto()
     else:
         if not obj.file:
             raise Exception("File not found")
         if obj.file.split(".")[-1] != 'csv':
             raise Exception("Wrong File")
         fpath = get_file_path(obj.file)
         data = open(fpath, "r").read().split("\n")
         att_ids = []
         records = {}
         for row in data:
             lines = row.split(",")
             if not lines:
                 continue
             size = len(lines)
             if size < 2:
                 continue
             if size > 2:
                 raise Exception("Wrong File")
             att_id = lines[0]
             att_date = lines[1]
             if not records.get(att_id):
                 records[att_id] = []
             records[att_id].append(att_date)
             continue
             # TODO Check format date
             if att_id not in att_ids:
                 att_ids.append(att_id)
         # self.set_att(ids,att_ids,context=context)
         emps = {emp['attendance_id']: emp['id']
                 for emp in get_model("hr.employee").search_read([], ['attendance_id'])}
         att = get_model("hr.attendance")
         at_ids = att.search([])
         # XXX testing
         att.delete(at_ids)
         for att_id, lines in records.items():
             att_id = int(att_id)
             date_list = []
             for line in lines:
                 datetime = line
                 date = datetime.split(" ")[0]
                 action = 'sign_in'
                 if date in date_list:
                     action = 'sign_out'
                     # FIXME find the last record and overwrite time
                 date_list.append(date)
                 att.create({
                     'employee_id': emps[att_id],
                     'action': action,
                     'time': datetime,
                 })
         print("Done!")
Beispiel #6
0
 def send_email_smtp(self, ids, context={}):
     print("send_email_smtp", ids)
     obj = self.browse(ids)[0]
     if obj.state not in ("draft", "to_send"):
         return
     try:
         mailbox = obj.mailbox_id
         if not mailbox:
             raise Exception("Missing mailbox")
         account = mailbox.account_id
         if account.type != "smtp":
             raise Exception("Invalid email account type")
         if account.security == "SSL":
             server = smtplib.SMTP_SSL(account.host,
                                       account.port or 465,
                                       timeout=30)
         else:
             server = smtplib.SMTP(account.host,
                                   account.port or 587,
                                   timeout=30)
         server.ehlo()
         if account.security == "starttls":
             server.starttls()
         if account.user:
             server.login(account.user, account.password)
         msg = MIMEMultipart()
         msg.set_charset("utf-8")
         msg["From"] = obj.from_addr
         msg["To"] = obj.to_addrs
         if obj.cc_addrs:
             msg["Cc"] = obj.cc_addrs
         msg["Subject"] = Header(obj.subject, "utf-8")
         msg.attach(MIMEText(obj.body, "html", "utf-8"))
         for attach in obj.attachments:
             path = utils.get_file_path(attach.file)
             data = open(path, "rb").read()
             part = MIMEBase('application', "octet-stream")
             part.set_payload(data)
             encode_base64(part)
             part.add_header('Content-Disposition',
                             'attachment; filename="%s"' % attach.file)
             msg.attach(part)
         to_addrs = obj.to_addrs.split(",")
         cc_addrs = obj.cc_addrs.split(",") if obj.cc_addrs else []
         server.sendmail(obj.from_addr, to_addrs + cc_addrs,
                         msg.as_string())
         obj.write({"state": "sent"})
         server.quit()
     except Exception as e:
         print("WARNING: failed to send email %s" % obj.id)
         import traceback
         traceback.print_exc()
         obj.write({"state": "error", "error_message": str(e)})
Beispiel #7
0
 def onchange_file(self, context={}):
     print("onchange_file")
     data = context["data"]
     filename = data["file"]
     if not filename:
         return
     categ_id = data["categ_id"]
     if not categ_id:
         return
     categ = get_model("document.categ").browse(categ_id)
     fmt = categ.file_name
     if not fmt:
         return
     contact_id = data.get("contact_id")
     if contact_id:
         contact = get_model("contact").browse(contact_id)
     else:
         contact = None
     date = data["date"]
     vals = {
         "contact_code": contact and contact.code or "",
         "doc_code": categ.code or "",
         "Y": date[0:4],
         "y": date[2:4],
         "m": date[5:7],
         "d": date[8:10],
     }
     filename2 = fmt % vals
     res = os.path.splitext(filename)
     rand = base64.urlsafe_b64encode(os.urandom(8)).decode()
     filename2 += "," + rand + res[1]
     if filename2 != filename:
         path = utils.get_file_path(filename)
         path2 = utils.get_file_path(filename2)
         os.rename(path, path2)
     return {
         "vals": {
             "file": filename2,
         }
     }
Beispiel #8
0
 def onchange_file(self, context={}):
     print("onchange_file")
     data = context["data"]
     filename = data["file"]
     if not filename:
         return
     categ_id = data["categ_id"]
     if not categ_id:
         return
     categ = get_model("document.categ").browse(categ_id)
     fmt = categ.file_name
     if not fmt:
         return
     contact_id = data.get("contact_id")
     if contact_id:
         contact = get_model("contact").browse(contact_id)
     else:
         contact = None
     date = data["date"]
     vals = {
         "contact_code": contact and contact.code or "",
         "doc_code": categ.code or "",
         "Y": date[0:4],
         "y": date[2:4],
         "m": date[5:7],
         "d": date[8:10],
     }
     filename2 = fmt % vals
     res = os.path.splitext(filename)
     rand = base64.urlsafe_b64encode(os.urandom(8)).decode()
     filename2 += "," + rand + res[1]
     if filename2 != filename:
         path = utils.get_file_path(filename)
         path2 = utils.get_file_path(filename2)
         os.rename(path, path2)
     return {
         "vals": {
             "file": filename2,
         }
     }
Beispiel #9
0
 def import_acc_file(self, ids, context):
     obj = self.browse(ids)[0]
     path = get_file_path(obj.file)
     data = open(path).read()
     rd = csv.reader(StringIO(data))
     headers = next(rd)
     headers = [h.strip() for h in headers]
     del_ids = get_model("conv.account").search([["conv_id", "=", obj.id]])
     get_model("conv.account").delete(del_ids)
     for row in rd:
         print("row", row)
         line = dict(zip(headers, row))
         print("line", line)
         if not line.get("Account"):
             continue
         acc_code = line["Account"].strip()
         if not acc_code:
             continue
         res = get_model("account.account").search([["code", "=", acc_code]])
         if not res:
             raise Exception("Account code not found: %s" % acc_code)
         acc_id = res[0]
         debit = float(line["Debit"].strip().replace(",", "") or 0)
         credit = float(line["Credit"].strip().replace(",", "") or 0)
         amount_cur = line["Currency Amt"].strip().replace(",", "")
         if amount_cur:
             amount_cur = float(amount_cur)
         else:
             amount_cur = None
         track_id=line.get('Track-1')
         if track_id:
             track_id = self.get_track_categ(track_id)
         track2_id=line.get('Track-2')
         if track2_id:
             track2_id = self.get_track_categ(track2_id)
         vals = {
             "conv_id": obj.id,
             "account_id": acc_id,
             "debit": debit,
             "credit": credit,
             "amount_cur": amount_cur,
             "track_id": track_id,
             "track2_id": track2_id,
         }
         get_model("conv.account").create(vals)
     return {
         "next": {
             "name": "conv_bal",
             "active_id": obj.id,
             "view_xml": "conv_bal1",
         }
     }
Beispiel #10
0
 def get_data(self, ids, context={}):
     settings = get_model("settings").browse(1)
     pages = []
     for obj in self.browse(ids):
         context['refer_id'] = obj.id
         data = self.get_payslip(context=context)
         pages.append(data)
     if pages:
         pages[-1]["is_last_page"] = True
     return {
         "pages": pages,
         "logo": get_file_path(settings.logo),
     }
Beispiel #11
0
 def get_data(self, ids, context={}):
     company_id = get_active_company()
     comp = get_model("company").browse(company_id)
     settings = get_model('settings').browse(1)
     pages = []
     for obj in self.browse(ids):
         lines = []
         for line in obj.lines:
             lines.append({
                 'description': line.description,
                 'account_code': line.account_id.code,
                 'account_name': line.account_id.name,
                 'debit': line.debit,
                 'credit': line.credit,
                 'tax_comp': line.tax_comp_id.name,
                 'tax_base': line.tax_base,
                 'track': line.track_id.name,
                 'contact': line.contact_id.name,
             })
         data = {
             "comp_name": comp.name,
             "number": obj.number,
             "date": obj.date,
             "journal": obj.journal_id.name,
             "narration": obj.narration,
             "lines": lines,
             "total_debit": obj.total_debit,
             "total_credit": obj.total_credit,
         }
         if settings.logo:
             data['logo'] = get_file_path(settings.logo)
         pages.append(data)
     if pages:
         pages[-1]["is_last_page"] = True
     return {
         "pages": pages,
         "logo":
         get_file_path(settings.logo),  # XXX: remove when render_odt fixed
     }
Beispiel #12
0
 def get_data(self, ids, context={}):
     settings = get_model("settings").browse(1)
     pages = []
     for obj in self.browse(ids):
         context['refer_id'] = obj.id
         data = self.get_payslip(context=context)
         pages.append(data)
     if pages:
         pages[-1]["is_last_page"] = True
     return {
         "pages": pages,
         "logo": get_file_path(settings.logo),
     }
Beispiel #13
0
def _get_report_path(name):
    fname = name + ".jrxml"
    report_dir = tempfile.mkdtemp()
    print("report_dir", report_dir)
    try:
        _extract_report_file(fname, report_dir)
    except:
        res = get_model("report.template").search([["name", "=", name]])
        if not res:
            raise Exception("Report template not found: %s" % name)
        tmpl_id = res[0]
        tmpl = get_model("report.template").browse(tmpl_id)
        in_path = utils.get_file_path(tmpl.file)
        data = open(in_path, "rb").read()
        out_path = os.path.join(report_dir, fname)
        f = open(out_path, "wb")
        f.write(data)
        f.close()
    report_path = os.path.join(report_dir, fname)
    tree = etree.parse(report_path)
    for el in tree.iterfind(
            ".//ns:imageExpression",
        {"ns": "http://jasperreports.sourceforge.net/jasperreports"}):
        expr = el.text
        m = re.match("^\"(.*)\"$", expr)
        if m:
            img_fname = m.group(1)
            img_path = utils.get_file_path(img_fname)
            if os.path.exists(img_path):
                img_path2 = os.path.join(report_dir, img_fname)
                shutil.copyfile(img_path, img_path2)
            else:
                _extract_report_file(img_fname, report_dir)
            el.text = '"' + os.path.join(report_dir, img_fname) + '"'
    report_xml = etree.tostring(tree, pretty_print=True).decode()
    f = open(report_path, "w")
    f.write(report_xml)
    f.close()
    return report_path
Beispiel #14
0
 def get_data(self, ids, context={}):
     company_id = get_active_company()
     comp = get_model("company").browse(company_id)
     settings = get_model('settings').browse(1)
     pages = []
     for obj in self.browse(ids):
         lines = []
         for line in obj.lines:
             lines.append({
                 'description': line.description,
                 'account_code': line.account_id.code,
                 'account_name': line.account_id.name,
                 'debit': line.debit,
                 'credit': line.credit,
                 'tax_comp': line.tax_comp_id.name,
                 'tax_base': line.tax_base,
                 'track': line.track_id.name,
                 'contact': line.contact_id.name,
             })
         data = {
             "comp_name": comp.name,
             "number": obj.number,
             "date": obj.date,
             "journal": obj.journal_id.name,
             "narration": obj.narration,
             "lines": lines,
             "total_debit": obj.total_debit,
             "total_credit": obj.total_credit,
         }
         if settings.logo:
             data['logo'] = get_file_path(settings.logo)
         pages.append(data)
     if pages:
         pages[-1]["is_last_page"] = True
     return {
         "pages": pages,
         "logo": get_file_path(settings.logo),  # XXX: remove when render_odt fixed
     }
Beispiel #15
0
 def send_email_mailgun(self, ids, context={}):
     print("send_emails_mailgun", ids)
     obj = self.browse(ids)[0]
     if obj.state not in ("draft", "to_send"):
         return
     try:
         mailbox = obj.mailbox_id
         if not mailbox:
             raise Exception("Missing mailbox")
         account = mailbox.account_id
         if account.type != "mailgun":
             raise Exception("Invalid email account type")
         url = "https://api.mailgun.net/v2/%s/messages" % account.user
         to_addrs = []
         for a in obj.to_addrs.split(","):
             a = a.strip()
             if not utils.check_email_syntax(a):
                 raise Exception("Invalid email syntax: %s" % a)
             to_addrs.append(a)
         if not to_addrs:
             raise Exception("Missing recipient address")
         data = {
             "from": obj.from_addr,
             "to": to_addrs,
             "subject": obj.subject,
         }
         if obj.cc_addrs:
             data["cc"] = [a.strip() for a in obj.cc_addrs.split(",")]
         data["html"] = obj.body or "<html><body></body></html>"
         files = []
         for attach in obj.attachments:
             path = utils.get_file_path(attach.file)
             f = open(path, "rb")
             files.append(("attachment", f))
         r = requests.post(url,
                           auth=("api", account.password),
                           data=data,
                           files=files,
                           timeout=15)
         try:
             res = json.loads(r.text)
             msg_id = res["id"]
         except:
             raise Exception("Invalid mailgun response: %s" % r.text)
         obj.write({"state": "sent", "message_id": msg_id})
     except Exception as e:
         print("WARNING: failed to send email %s" % obj.id)
         import traceback
         traceback.print_exc()
         obj.write({"state": "error", "error_message": str(e)})
Beispiel #16
0
def _get_report_path(name):
    fname = name + ".jrxml"
    report_dir = tempfile.mkdtemp()
    print("report_dir", report_dir)
    try:
        _extract_report_file(fname, report_dir)
    except:
        res = get_model("report.template").search([["name", "=", name]])
        if not res:
            raise Exception("Report template not found: %s" % name)
        tmpl_id = res[0]
        tmpl = get_model("report.template").browse(tmpl_id)
        in_path = utils.get_file_path(tmpl.file)
        data = open(in_path, "rb").read()
        out_path = os.path.join(report_dir, fname)
        f = open(out_path, "wb")
        f.write(data)
        f.close()
    report_path = os.path.join(report_dir, fname)
    tree = etree.parse(report_path)
    for el in tree.iterfind(".//ns:imageExpression", {"ns": "http://jasperreports.sourceforge.net/jasperreports"}):
        expr = el.text
        m = re.match("^\"(.*)\"$", expr)
        if m:
            img_fname = m.group(1)
            img_path = utils.get_file_path(img_fname)
            if os.path.exists(img_path):
                img_path2 = os.path.join(report_dir, img_fname)
                shutil.copyfile(img_path, img_path2)
            else:
                _extract_report_file(img_fname, report_dir)
            el.text = '"' + os.path.join(report_dir, img_fname) + '"'
    report_xml = etree.tostring(tree, pretty_print=True).decode()
    f = open(report_path, "w")
    f.write(report_xml)
    f.close()
    return report_path
Beispiel #17
0
def get_report_template(name, report_type):
    db = database.get_connection()
    res = db.get("SELECT file FROM report_template WHERE name=%s AND format=%s", name, report_type)
    if res:
        path = utils.get_file_path(res.file)
        data = open(path, "rb").read()
        return data
    loaded_modules = module.get_loaded_modules()
    for m in reversed(loaded_modules):
        f = "reports/" + name + "." + report_type
        if not pkg_resources.resource_exists(m, f):
            continue
        data = pkg_resources.resource_string(m, f)
        return data
    raise Exception("Report not found: %s" % name)
Beispiel #18
0
    def get_data_pick_internal_form(self, context={}):
        company_id = get_active_company()
        comp = get_model("company").browse(company_id)
        obj_id = int(context["refer_id"])
        obj = get_model("stock.picking").browse(obj_id)
        settings = get_model("settings").browse(1)
        comp_addr = settings.get_address_str()
        comp_name = comp.name
        comp_phone = settings.phone
        comp_fax = settings.fax
        comp_tax_no = settings.tax_no
        contact = obj.contact_id
        cust_addr = contact.get_address_str()
        cust_name = contact.name
        cust_fax = contact.fax
        cust_phone = contact.phone
        cust_tax_no = contact.tax_no

        data = {
            "comp_name": comp_name,
            "comp_addr": comp_addr,
            "comp_phone": comp_phone or "-",
            "comp_fax": comp_fax or "-",
            "comp_tax_no": comp_tax_no or "-",
            "cust_name": cust_name,
            "cust_addr": cust_addr,
            "cust_phone": cust_phone or "-",
            "cust_fax": cust_fax or "-",
            "cust_tax_no": cust_tax_no or "-",
            "date": obj.date,
            "number": obj.number,
            "ref": obj.ref,
            "lines": [],
        }
        if settings.logo:
            data["logo"] = get_file_path(settings.logo)
        for line in obj.lines:
            data["lines"].append({
                "product": line.product_id.name,
                "description": line.product_id.description,
                "qty": line.qty,
                "uom": line.uom_id.name,
                "location_from": line.location_from_id.name,
                "location_to": line.location_to_id.name,
                "cost_price": line.cost_price,
            })
        return data
Beispiel #19
0
    def get_data_pick_internal_form(self, context={}):
        company_id = get_active_company()
        comp = get_model("company").browse(company_id)
        obj_id = int(context["refer_id"])
        obj = get_model("stock.picking").browse(obj_id)
        settings = get_model("settings").browse(1)
        comp_addr = settings.get_address_str()
        comp_name = comp.name
        comp_phone = settings.phone
        comp_fax = settings.fax
        comp_tax_no = settings.tax_no
        contact = obj.contact_id
        cust_addr = contact.get_address_str()
        cust_name = contact.name
        cust_fax = contact.fax
        cust_phone = contact.phone
        cust_tax_no = contact.tax_no

        data = {
            "comp_name": comp_name,
            "comp_addr": comp_addr,
            "comp_phone": comp_phone or "-",
            "comp_fax": comp_fax or "-",
            "comp_tax_no": comp_tax_no or "-",
            "cust_name": cust_name,
            "cust_addr": cust_addr,
            "cust_phone": cust_phone or "-",
            "cust_fax": cust_fax or "-",
            "cust_tax_no": cust_tax_no or "-",
            "date": obj.date,
            "number": obj.number,
            "ref": obj.ref,
            "lines": [],
        }
        if settings.logo:
            data["logo"] = get_file_path(settings.logo)
        for line in obj.lines:
            data["lines"].append({
                "product": line.product_id.name,
                "description": line.product_id.description,
                "qty": line.qty,
                "uom": line.uom_id.name,
                "location_from": line.location_from_id.name,
                "location_to": line.location_to_id.name,
                "cost_price": line.cost_price,
            })
        return data
Beispiel #20
0
def get_report_template(name, report_type):
    db = database.get_connection()
    res = db.get(
        "SELECT file FROM report_template WHERE name=%s AND format=%s", name,
        report_type)
    if res:
        path = utils.get_file_path(res.file)
        data = open(path, "rb").read()
        return data
    loaded_modules = module.get_loaded_modules()
    for m in reversed(loaded_modules):
        f = "reports/" + name + "." + report_type
        if not pkg_resources.resource_exists(m, f):
            continue
        data = pkg_resources.resource_string(m, f)
        return data
    raise Exception("Report not found: %s" % name)
Beispiel #21
0
 def send_email_mailgun(self, ids, context={}):
     print("send_emails_mailgun", ids)
     obj = self.browse(ids)[0]
     if obj.state not in ("draft","to_send"):
         return
     try:
         mailbox = obj.mailbox_id
         if not mailbox:
             raise Exception("Missing mailbox")
         account = mailbox.account_id
         if account.type != "mailgun":
             raise Exception("Invalid email account type")
         url = "https://api.mailgun.net/v2/%s/messages" % account.user
         to_addrs = []
         for a in obj.to_addrs.split(","):
             a = a.strip()
             if not utils.check_email_syntax(a):
                 raise Exception("Invalid email syntax: %s" % a)
             to_addrs.append(a)
         if not to_addrs:
             raise Exception("Missing recipient address")
         data = {
             "from": obj.from_addr,
             "to": to_addrs,
             "subject": obj.subject,
         }
         if obj.cc_addrs:
             data["cc"] = [a.strip() for a in obj.cc_addrs.split(",")]
         data["html"] = obj.body or "<html><body></body></html>"
         files = []
         for attach in obj.attachments:
             path = utils.get_file_path(attach.file)
             f = open(path, "rb")
             files.append(("attachment", f))
         r = requests.post(url, auth=("api", account.password), data=data, files=files,timeout=15)
         try:
             res = json.loads(r.text)
             msg_id = res["id"]
         except:
             raise Exception("Invalid mailgun response: %s" % r.text)
         obj.write({"state": "sent", "message_id": msg_id})
     except Exception as e:
         print("WARNING: failed to send email %s" % obj.id)
         import traceback
         traceback.print_exc()
         obj.write({"state": "error", "error_message": str(e)})
Beispiel #22
0
    def send_email_smtp(self, ids, context={}):
        print("send_email_smtp", ids)
        obj = self.browse(ids)[0]
        if obj.state not in ("draft", "to_send"):
            return
        try:
            mailbox = obj.mailbox_id
            if not mailbox:
                raise Exception("Missing mailbox")
            account = mailbox.account_id
            if account.type != "smtp":
                raise Exception("Invalid email account type")
            if account.security == "SSL":
                server = smtplib.SMTP_SSL(account.host, account.port or 465, timeout=30)
            else:
                server = smtplib.SMTP(account.host, account.port or 587, timeout=30)
            server.ehlo()
            if account.security == "starttls":
                server.starttls()
            if account.user:
                server.login(account.user, account.password)
            msg = MIMEMultipart()
            msg.set_charset("utf-8")
            msg["From"] = obj.from_addr
            msg["To"] = obj.to_addrs
            msg["Subject"] = Header(obj.subject, "utf-8")
            msg.attach(MIMEText(obj.body, "html", "utf-8"))
            for attach in obj.attachments:
                path = utils.get_file_path(attach.file)
                data = open(path, "rb").read()
                part = MIMEBase("application", "octet-stream")
                part.set_payload(data)
                encode_base64(part)
                part.add_header("Content-Disposition", 'attachment; filename="%s"' % attach.file)
                msg.attach(part)
            to_addrs = obj.to_addrs.split(",")
            server.sendmail(obj.from_addr, to_addrs, msg.as_string())
            obj.write({"state": "sent"})
            server.quit()
        except Exception as e:
            print("WARNING: failed to send email %s" % obj.id)
            import traceback

            traceback.print_exc()
            obj.write({"state": "error", "error_message": str(e)})
Beispiel #23
0
 def import_acc_file(self, ids, context):
     obj = self.browse(ids)[0]
     path = get_file_path(obj.file)
     data = open(path).read()
     rd = csv.reader(StringIO(data))
     headers = next(rd)
     headers = [h.strip() for h in headers]
     del_ids = get_model("conv.account").search([["conv_id", "=", obj.id]])
     get_model("conv.account").delete(del_ids)
     for row in rd:
         print("row", row)
         line = dict(zip(headers, row))
         print("line", line)
         if not line.get("Account"):
             continue
         acc_code = line["Account"].strip()
         if not acc_code:
             continue
         res = get_model("account.account").search([["code", "=", acc_code]])
         if not res:
             raise Exception("Account code not found: %s" % acc_code)
         acc_id = res[0]
         debit = float(line["Debit"].strip().replace(",", "") or 0)
         credit = float(line["Credit"].strip().replace(",", "") or 0)
         amount_cur = line["Currency Amt"].strip().replace(",", "")
         if amount_cur:
             amount_cur = float(amount_cur)
         else:
             amount_cur = None
         vals = {
             "conv_id": obj.id,
             "account_id": acc_id,
             "debit": debit,
             "credit": credit,
             "amount_cur": amount_cur,
         }
         get_model("conv.account").create(vals)
     return {
         "next": {
             "name": "conv_bal",
             "active_id": obj.id,
             "view_xml": "conv_bal1",
         }
     }
Beispiel #24
0
 def load_templates(self, ids, context={}):
     obj = self.browse(ids[0])
     if obj.file:
         zip_path = utils.get_file_path(obj.file)
         zf = zipfile.ZipFile(zip_path)
         for n in zf.namelist():
             if not n.startswith("templates/"):
                 continue
             if not n.endswith(".hbs"):
                 continue
             n2 = n[10:-4]
             if n2.find("..") != -1:
                 continue
             print("load template", n2)
             data = zf.read(n)
             vals = {
                 "name": n2,
                 "template": data.decode(),
                 "theme_id": obj.id,
             }
             get_model("template").merge(vals)
     else:
         theme = obj.name
         loaded_modules = module.get_loaded_modules()
         for m in reversed(loaded_modules):
             if not pkg_resources.resource_isdir(
                     m, "themes/" + theme + "/templates"):
                 continue
             for f in pkg_resources.resource_listdir(
                     m, "themes/" + theme + "/templates"):
                 if not f.endswith(".hbs"):
                     continue
                 f2 = f[:-4]
                 print("load template", f2)
                 data = pkg_resources.resource_string(
                     m, "themes/" + theme + "/templates/" + f)
                 vals = {
                     "name": f2,
                     "template": data.decode(),
                     "theme_id": obj.id,
                 }
                 get_model("template").merge(vals)
Beispiel #25
0
 def import_bank_file(self, ids, context={}):
     obj = self.browse(ids)[0]
     path = get_file_path(obj.bank_file)
     data = open(path).read()
     rd = csv.reader(StringIO(data))
     headers = next(rd)
     headers = [h.strip() for h in headers]
     for row in rd:
         print("row", row)
         line = dict(zip(headers, row))
         print("line", line)
         vals = {
             "import_id": obj.id,
             "type": "bank",
             "date": parse_date(line["Date"], obj.date_fmt),
             "description": line["Description"],
             "received": parse_float(line["Received"]),
             "spent": parse_float(line["Spent"]),
             "invoice_no": line["Invoice No."],
             "other_account_id": get_account(line["Other Account"]),
         }
         get_model("batch.import.payment").create(vals)
Beispiel #26
0
 def load_templates(self, ids, context={}):
     obj = self.browse(ids[0])
     if obj.file:
         zip_path = utils.get_file_path(obj.file)
         zf = zipfile.ZipFile(zip_path)
         for n in zf.namelist():
             if not n.startswith("templates/"):
                 continue
             if not n.endswith(".hbs"):
                 continue
             n2 = n[10:-4]
             if n2.find("..") != -1:
                 continue
             print("load template", n2)
             data = zf.read(n)
             vals = {
                 "name": n2,
                 "template": data.decode(),
                 "theme_id": obj.id,
             }
             get_model("template").merge(vals)
     else:
         theme = obj.name
         loaded_modules = module.get_loaded_modules()
         for m in reversed(loaded_modules):
             if not pkg_resources.resource_isdir(m, "themes/" + theme + "/templates"):
                 continue
             for f in pkg_resources.resource_listdir(m, "themes/" + theme + "/templates"):
                 if not f.endswith(".hbs"):
                     continue
                 f2 = f[:-4]
                 print("load template", f2)
                 data = pkg_resources.resource_string(m, "themes/" + theme + "/templates/" + f)
                 vals = {
                     "name": f2,
                     "template": data.decode(),
                     "theme_id": obj.id,
                 }
                 get_model("template").merge(vals)
Beispiel #27
0
 def import_bank_file(self, ids, context={}):
     obj = self.browse(ids)[0]
     path = get_file_path(obj.bank_file)
     data = open(path).read()
     rd = csv.reader(StringIO(data))
     headers = next(rd)
     headers = [h.strip() for h in headers]
     for row in rd:
         print("row", row)
         line = dict(zip(headers, row))
         print("line", line)
         vals = {
             "import_id": obj.id,
             "type": "bank",
             "date": parse_date(line["Date"], obj.date_fmt),
             "description": line["Description"],
             "received": parse_float(line["Received"]),
             "spent": parse_float(line["Spent"]),
             "invoice_no": line["Invoice No."],
             "other_account_id": get_account(line["Other Account"]),
         }
         get_model("batch.import.payment").create(vals)
Beispiel #28
0
 def import_purchase_file(self, ids, context={}):
     obj = self.browse(ids)[0]
     path = get_file_path(obj.purchase_file)
     data = open(path).read()
     rd = csv.reader(StringIO(data))
     headers = next(rd)
     headers = [h.strip() for h in headers]
     for row in rd:
         print("row", row)
         line = dict(zip(headers, row))
         print("line", line)
         vals = {
             "import_id": obj.id,
             "date": parse_date(line["Date"], obj.date_fmt),
             "number": line["Invoice No."],
             "contact": line["Supplier Name"],
             "description": line["Description"],
             "amount": parse_float(line["Amount"]),
             "account_id": get_account(line["Expense Account"]),
             "tax_id": get_tax_rate(line["Tax Rate"]),
         }
         get_model("batch.import.purchase.invoice").create(vals)
Beispiel #29
0
 def import_purchase_file(self, ids, context={}):
     obj = self.browse(ids)[0]
     path = get_file_path(obj.purchase_file)
     data = open(path).read()
     rd = csv.reader(StringIO(data))
     headers = next(rd)
     headers = [h.strip() for h in headers]
     for row in rd:
         print("row", row)
         line = dict(zip(headers, row))
         print("line", line)
         vals = {
             "import_id": obj.id,
             "date": parse_date(line["Date"], obj.date_fmt),
             "number": line["Invoice No."],
             "contact": line["Supplier Name"],
             "description": line["Description"],
             "amount": parse_float(line["Amount"]),
             "account_id": get_account(line["Expense Account"]),
             "tax_id": get_tax_rate(line["Tax Rate"]),
         }
         get_model("batch.import.purchase.invoice").create(vals)
Beispiel #30
0
def get_theme_static_data(theme_name, path):
    print("get_theme_static_data", theme_name, path)
    db = database.get_connection()
    if not db:
        return None
    res = db.get("SELECT file FROM cms_theme WHERE name=%s", theme_name)
    if not res:
        return None
    if res.file:
        zip_path = utils.get_file_path(res.file)
        zip_data = open(zip_path, "rb").read()
        f = BytesIO(zip_data)
        zf = zipfile.ZipFile(f)
        try:
            data = zf.read("static/" + path)
            return data
        except:
            return None
    else:
        data = module.read_module_file("themes/" + theme_name + "/static/" + path)
        if data:
            return data
    return None
Beispiel #31
0
def get_theme_static_data(theme_name, path):
    print("get_theme_static_data", theme_name, path)
    db = database.get_connection()
    if not db:
        return None
    res = db.get("SELECT file FROM cms_theme WHERE name=%s", theme_name)
    if not res:
        return None
    if res.file:
        zip_path = utils.get_file_path(res.file)
        zip_data = open(zip_path, "rb").read()
        f = BytesIO(zip_data)
        zf = zipfile.ZipFile(f)
        try:
            data = zf.read("static/" + path)
            return data
        except:
            return None
    else:
        data = module.read_module_file("themes/" + theme_name + "/static/" +
                                       path)
        if data:
            return data
    return None
Beispiel #32
0
 def export_static_files(self, ids, context={}):
     obj = self.browse(ids)[0]
     theme = obj.name
     dbname = get_active_db()
     if obj.file:
         zip_path = utils.get_file_path(obj.file)
         zf = zipfile.ZipFile(zip_path)
         for n in zf.namelist():
             if not n.startswith("static/"):
                 continue
             if n[-1] == "/":
                 continue
             n2 = n[7:]
             if n2.find("..") != -1:
                 continue
             data = zf.read(n)
             f_path = "static/db/" + dbname + "/themes/" + theme + "/" + n2
             dir_path = os.path.dirname(f_path)
             if not os.path.exists(dir_path):
                 os.makedirs(dir_path)
             print("export file", f_path)
             open(f_path, "wb").write(data)
     else:
         export_module_file_all("themes/" + theme + "/static", "static/db/" + dbname + "/themes/" + theme)
Beispiel #33
0
 def import_purch_file(self, ids, context):
     obj = self.browse(ids)[0]
     path = get_file_path(obj.file)
     data = open(path).read()
     rd = csv.reader(StringIO(data))
     headers = next(rd)
     headers = [h.strip() for h in headers]
     del_ids = get_model("conv.purch.invoice").search([["conv_id", "=", obj.id]])
     get_model("conv.purch.invoice").delete(del_ids)
     i = 1
     for row in rd:
         i += 1
         try:
             print("row", row)
             line = dict(zip(headers, row))
             print("line", line)
             if not line.get("Number"):
                 continue
             number = line["Number"].strip()
             if not number:
                 continue
             ref = line["Reference"].strip()
             contact_name = line["Contact"].strip()
             res = get_model("contact").search([["name", "=", contact_name]])
             if not res:
                 raise Exception("Contact not found: '%s'" % contact_name)
             contact_id = res[0]
             date = datetime.datetime.strptime(line["Date"].strip(), obj.date_fmt).strftime("%Y-%m-%d")
             due_date = datetime.datetime.strptime(line["Due Date"].strip(), obj.date_fmt).strftime("%Y-%m-%d")
             amount_due = float(line["Amount Due"].strip().replace(",", "") or 0)
             acc_code = line["Account"].strip()
             if not acc_code:
                 raise Exception("Account is missing")
             res = get_model("account.account").search([["code", "=", acc_code]])
             if not res:
                 raise Exception("Account code not found: %s" % acc_code)
             acc_id = res[0]
             amount_cur=None
             if line.get("Currency Amt"):
                 amount_cur = line["Currency Amt"].strip().replace(",", "")
                 amount_cur = float(amount_cur)
             track_id=line.get('Track-1')
             if track_id:
                 track_id = self.get_track_categ(track_id)
             track2_id=line.get('Track-2')
             if track2_id:
                 track2_id = self.get_track_categ(track2_id)
             vals = {
                 "conv_id": obj.id,
                 "number": number,
                 "ref": ref,
                 "contact_id": contact_id,
                 "date": date,
                 "due_date": due_date,
                 "amount_due": amount_due,
                 "account_id": acc_id,
                 "amount_cur": amount_cur,
                 "track_id": track_id,
                 "track2_id": track2_id,
             }
             get_model("conv.purch.invoice").create(vals)
         except Exception as e:
             raise Exception("Error line %d: %s" % (i, e))
     return {
         "next": {
             "name": "conv_bal",
             "active_id": obj.id,
             "view_xml": "conv_bal3",
         }
     }
Beispiel #34
0
 def get_data_form(self, context={}):
     inv_id = context.get("invoice_id")  # XXX: old, move this
     if not inv_id:
         inv_id = context["refer_id"]
     inv_id = int(inv_id)
     inv = get_model("account.invoice").browse(inv_id)
     dbname = database.get_active_db()
     company = inv.company_id
     settings = get_model("settings").browse(1)
     comp_addr = settings.get_address_str()
     comp_name = company.name
     comp_phone = settings.phone
     comp_fax = settings.fax
     comp_tax_no = settings.tax_no
     contact = inv.contact_id
     cust_addr = contact.get_address_str()
     cust_name = contact.name
     cust_fax = contact.fax
     cust_phone = contact.phone
     cust_tax_no = contact.tax_no
     data = {
         "comp_name": comp_name,
         "comp_addr": comp_addr,
         "comp_phone": comp_phone or "-",
         "comp_fax": comp_fax or "-",
         "comp_tax_no": comp_tax_no or "-",
         "cust_name": cust_name,
         "cust_addr": cust_addr,
         "cust_phone": cust_phone or "-",
         "cust_fax": cust_fax or "-",
         "cust_tax_no": cust_tax_no or "-",
         "date": inv.date or "-",
         "due_date": inv.due_date or "-",
         "number": inv.number or "-",
         "ref": inv.ref or "-",
         "memo": inv.memo or "",
         "lines": [],
     }
     if settings.logo:
         data["logo"] = get_file_path(settings.logo)
     for line in inv.lines:
         data["lines"].append({
             "description": line.description,
             "code": line.product_id.code,
             "qty": line.qty,
             "uom": line.uom_id.name,
             "unit_price": line.unit_price,
             "discount": line.discount,
             "tax_rate": line.tax_id.rate,
             "amount": line.amount,
         })
     is_cash = 'No'
     is_cheque = 'No'
     for obj in inv.payments:
         account_type = obj.payment_id.account_id.type
         if account_type in ("bank", "cash"):
             is_cash = 'Yes'
         if account_type in ("cheque"):
             is_cheque = 'Yes'
     data.update({
         "amount_subtotal":
         inv.amount_subtotal,
         "amount_discount":
         inv.amount_discount,
         "amount_tax":
         inv.amount_tax,
         "amount_total":
         inv.amount_total,
         "amount_paid":
         inv.amount_paid,
         "payment_terms":
         inv.related_id.payment_terms or "-",
         "is_cash":
         is_cash,
         "is_cheque":
         is_cheque,
         "currency_code":
         inv.currency_id.code,
         "tax_rate":
         round(inv.amount_tax * 100.0 / inv.amount_subtotal or 0, 2),
         "qty_total":
         inv.qty_total,
         "memo":
         inv.memo,
     })
     if inv.credit_alloc:
         data.update({
             "original_inv_subtotal":
             inv.credit_alloc[0].invoice_id.amount_subtotal,
         })
     return data
Beispiel #35
0
 def import_purch_file(self, ids, context):
     obj = self.browse(ids)[0]
     path = get_file_path(obj.file)
     data = open(path).read()
     rd = csv.reader(StringIO(data))
     headers = next(rd)
     headers = [h.strip() for h in headers]
     del_ids = get_model("conv.purch.invoice").search([["conv_id", "=", obj.id]])
     get_model("conv.purch.invoice").delete(del_ids)
     i = 1
     for row in rd:
         i += 1
         try:
             print("row", row)
             line = dict(zip(headers, row))
             print("line", line)
             if not line.get("Number"):
                 continue
             number = line["Number"].strip()
             if not number:
                 continue
             ref = line["Reference"].strip()
             contact_name = line["Contact"].strip()
             res = get_model("contact").search([["name", "=", contact_name]])
             if not res:
                 raise Exception("Contact not found: '%s'" % contact_name)
             contact_id = res[0]
             date = datetime.datetime.strptime(line["Date"].strip(), obj.date_fmt).strftime("%Y-%m-%d")
             due_date = datetime.datetime.strptime(line["Due Date"].strip(), obj.date_fmt).strftime("%Y-%m-%d")
             amount_due = float(line["Amount Due"].strip().replace(",", "") or 0)
             acc_code = line["Account"].strip()
             if not acc_code:
                 raise Exception("Account is missing")
             res = get_model("account.account").search([["code", "=", acc_code]])
             if not res:
                 raise Exception("Account code not found: %s" % acc_code)
             acc_id = res[0]
             amount_cur = line["Amount Cur"].strip().replace(",", "")
             if amount_cur:
                 amount_cur = float(amount_cur)
             else:
                 amount_cur = None
             vals = {
                 "conv_id": obj.id,
                 "number": number,
                 "ref": ref,
                 "contact_id": contact_id,
                 "date": date,
                 "due_date": due_date,
                 "amount_due": amount_due,
                 "account_id": acc_id,
                 "amount_cur": amount_cur,
             }
             get_model("conv.purch.invoice").create(vals)
         except Exception as e:
             raise Exception("Error line %d: %s" % (i, e))
     return {
         "next": {
             "name": "conv_bal",
             "active_id": obj.id,
             "view_xml": "conv_bal3",
         }
     }
Beispiel #36
0
    def get_payslip(self, context={}):
        if not context.get('refer_id'):
            return {}
        payslip_id = int(context['refer_id'])
        payslip = self.browse(payslip_id)
        employee = payslip.employee_id
        title = employee.title or ""
        employee_name = "%s. %s %s" % (title.title(), employee.first_name
                                       or '', employee.last_name or '')
        employee_address = get_model('hr.employee').get_address([employee.id])
        lines = []
        income = []
        deduct = []
        for line in payslip.lines:
            type = line.payitem_id.type
            if type in ('wage', 'allow'):
                income.append({
                    'income': 1,
                    'item': line.payitem_id.name,
                    'amount': line.amount,
                })
            else:
                deduct.append({
                    'income': 0,
                    'item': line.payitem_id.name,
                    'amount': line.amount,
                })

        range_amt = len(income) if len(income) > len(deduct) else len(deduct)
        total_deduct = 0.0
        total_income = 0.0
        for i in range(range_amt):
            line = {}
            if i < len(income):
                item = income[i]
                total_income += item['amount']
                line.update({
                    'income_description': item['item'],
                    'income_amt': item['amount'],
                    'income_no': i + 1,
                })
            if i < len(deduct):
                item = deduct[i]
                total_deduct += item['amount']
                line.update({
                    'deduct_description': item['item'],
                    'deduct_amt': item['amount'],
                    'deduct_no': i + 1,
                })
            lines.append(line)
        data = {
            'ref': payslip.run_id.number,
            'date': payslip.date,
            'employee_name': employee_name,
            'employee_address': employee_address or "Empty Address",
            'amount_net': payslip.amount_net,
            'total_deduct': total_deduct,
            'total_income': total_income,
            'lines': lines
        }
        comp = get_model('settings').browse(1)
        if comp.logo:
            data['logo'] = get_file_path(comp.logo)
        return data
    def get_data_purchase_form(self, context={}):
        obj_id = int(context["refer_id"])
        obj = get_model("purchase.order").browse(obj_id)
        dbname = database.get_active_db()
        settings = get_model("settings").browse(1)
        comp_name = settings.name
        comp_phone = settings.phone
        comp_fax = settings.fax
        comp_addr = settings.get_address_str()
        comp_tax_no = settings.tax_no
        contact = obj.contact_id
        cust_name = contact.name
        cust_fax = contact.fax
        cust_phone = contact.phone
        cust_tax_no = contact.tax_no
        cust_addr = contact.get_address_str()
        data = {
            "comp_name": comp_name,
            "comp_addr": comp_addr,
            "comp_phone": comp_phone or "-",
            "comp_fax": comp_fax or "-",
            "comp_tax_no": comp_tax_no or "-",
            "cust_name": cust_name,
            "cust_addr": cust_addr,
            "cust_phone": cust_phone or "-",
            "cust_fax": cust_fax or "-",
            "cust_tax_no": cust_tax_no or "-",
            "date": obj.date or "-",
            "number": obj.number or "-",
            "ref": obj.ref or "-",
            "delivery_date": obj.delivery_date or "-",
            "ship_method": obj.ship_method_id.name or "-",
            "payment_terms": obj.payment_terms or "-",
            "lines": [],
        }
        index = 0
        for line in obj.lines:
            if line.tax_id:
                break
            index += 1
        if not index:
            tax_rate = obj.lines[index].tax_id.rate
            tax_rate = tax_rate and tax_rate or "0"
        else:
            tax_rate = "0"

        if settings.logo:
            data["logo"] = get_file_path(settings.logo)
        for line in obj.lines:
            data["lines"].append({
                "code": line.product_id.code,
                "description": line.description,
                "qty": line.qty,
                "uom": line.uom_id.name,
                "unit_price": line.unit_price,
                "tax_rate": line.tax_id.rate,
                "amount": line.amount,
            })
        data.update({
            "amount_subtotal": obj.amount_subtotal,
            "amount_tax": obj.amount_tax,
            "amount_total": obj.amount_total,
            "amount_total_words": utils.num2word(obj.amount_total),
            "currency_code": obj.currency_id.code,
            "tax_rate": int(tax_rate),
            "qty_total": obj.qty_total
        })
        return data
Beispiel #38
0
 def get_report_data(self, ids=None, context={}):  # XXX: deprecated
     print("invoice.get_report_data")
     if ids is not None:  # for new templates
         return super().get_report_data(ids, context=context)
     ids = context["ids"]
     print("ids", ids, type(ids))
     inv_id = ids[0]
     inv = get_model("account.invoice").browse(inv_id)
     dbname = database.get_active_db()
     company = inv.company_id
     settings = get_model("settings").browse(1)
     comp_addr = settings.get_address_str()
     comp_name = company.name
     comp_phone = settings.phone
     comp_fax = settings.fax
     comp_tax_no = settings.tax_no
     contact = inv.contact_id
     cust_addr = contact.get_address_str()
     cust_name = contact.name
     cust_fax = contact.fax
     cust_phone = contact.phone
     cust_tax_no = contact.tax_no
     data = {
         "comp_name": comp_name,
         "comp_addr": comp_addr,
         "comp_phone": comp_phone or "-",
         "comp_fax": comp_fax or "-",
         "comp_tax_no": comp_tax_no or "-",
         "cust_name": cust_name,
         "cust_addr": cust_addr,
         "cust_phone": cust_phone or "-",
         "cust_fax": cust_fax or "-",
         "cust_tax_no": cust_tax_no or "-",
         "date": inv.date or "-",
         "due_date": inv.due_date or "-",
         "number": inv.number or "-",
         "ref": inv.ref or "-",
         "memo": inv.memo or "",
         "lines": [],
     }
     if settings.logo:
         data["logo"] = get_file_path(settings.logo)
     for line in inv.lines:
         data["lines"].append({
             "description": line.description,
             "code": line.product_id.code,
             "qty": line.qty,
             "uom": line.uom_id.name,
             "unit_price": line.unit_price,
             "discount": line.discount,
             "tax_rate": line.tax_id.rate,
             "amount": line.amount,
         })
     is_cash = 'No'
     is_cheque = 'No'
     for obj in inv.payments:
         account_type = obj.payment_id.account_id.type
         if account_type in ("bank", "cash"):
             is_cash = 'Yes'
         if account_type in ("cheque"):
             is_cheque = 'Yes'
     data.update({
         "amount_subtotal": inv.amount_subtotal,
         "amount_discount": inv.amount_discount,
         "amount_tax": inv.amount_tax,
         "amount_total": inv.amount_total,
         "amount_paid": inv.amount_paid,
         "payment_terms": inv.related_id.payment_terms or "-",
         "is_cash": is_cash,
         "is_cheque": is_cheque,
         "currency_code": inv.currency_id.code,
         "tax_rate": get_model("currency").round(inv.currency_id.id,inv.amount_tax * 100 / inv.amount_subtotal) if inv.amount_subtotal else 0,
         "qty_total": inv.qty_total,
         "memo": inv.memo,
     })
     if inv.credit_alloc:
         data.update({
             "original_inv_subtotal": inv.credit_alloc[0].invoice_id.amount_subtotal,
         })
     return data
Beispiel #39
0
    def get_payslip(self, context={}):
        if not context.get('refer_id'):
            return {}
        payslip_id = int(context['refer_id'])
        payslip = self.browse(payslip_id)
        employee = payslip.employee_id
        title = employee.title or ""
        employee_name = "%s. %s %s" % (title.title(), employee.first_name or '', employee.last_name or '')
        employee_address = get_model('hr.employee').get_address([employee.id])
        lines = []
        income = []
        deduct = []
        for line in payslip.lines:
            type = line.payitem_id.type
            if type in ('wage', 'allow'):
                income.append({
                    'income': 1,
                    'item': line.payitem_id.name,
                    'amount': line.amount,
                })
            else:
                deduct.append({
                    'income': 0,
                    'item': line.payitem_id.name,
                    'amount': line.amount,
                })

        range_amt = len(income) if len(income) > len(deduct) else len(deduct)
        total_deduct = 0.0
        total_income = 0.0
        for i in range(range_amt):
            line = {}
            if i < len(income):
                item = income[i]
                total_income += item['amount']
                line.update({
                    'income_description': item['item'],
                    'income_amt': item['amount'],
                    'income_no': i + 1,
                })
            if i < len(deduct):
                item = deduct[i]
                total_deduct += item['amount']
                line.update({
                    'deduct_description': item['item'],
                    'deduct_amt': item['amount'],
                    'deduct_no': i + 1,
                })
            lines.append(line)
        data = {
            'ref': payslip.run_id.number,
            'date': payslip.date,
            'employee_name': employee_name,
            'employee_address': employee_address or "Empty Address",
            'amount_net': payslip.amount_net,
            'total_deduct': total_deduct,
            'total_income': total_income,
            'lines': lines
        }
        comp = get_model('settings').browse(1)
        if comp.logo:
            data['logo'] = get_file_path(comp.logo)
        return data
Beispiel #40
0
 def get_data_form(self, context={}):
     inv_id = context.get("invoice_id")  # XXX: old, move this
     if not inv_id:
         inv_id = context["refer_id"]
     inv_id = int(inv_id)
     inv = get_model("account.invoice").browse(inv_id)
     dbname = database.get_active_db()
     company = inv.company_id
     settings = get_model("settings").browse(1)
     comp_addr = settings.get_address_str()
     comp_name = company.name
     comp_phone = settings.phone
     comp_fax = settings.fax
     comp_tax_no = settings.tax_no
     contact = inv.contact_id
     cust_addr = contact.get_address_str()
     cust_name = contact.name
     cust_fax = contact.fax
     cust_phone = contact.phone
     cust_tax_no = contact.tax_no
     data = {
         "comp_name": comp_name,
         "comp_addr": comp_addr,
         "comp_phone": comp_phone or "-",
         "comp_fax": comp_fax or "-",
         "comp_tax_no": comp_tax_no or "-",
         "cust_name": cust_name,
         "cust_addr": cust_addr,
         "cust_phone": cust_phone or "-",
         "cust_fax": cust_fax or "-",
         "cust_tax_no": cust_tax_no or "-",
         "date": inv.date or "-",
         "due_date": inv.due_date or "-",
         "number": inv.number or "-",
         "ref": inv.ref or "-",
         "memo": inv.memo or "",
         "lines": [],
     }
     if settings.logo:
         data["logo"] = get_file_path(settings.logo)
     for line in inv.lines:
         data["lines"].append({
             "description": line.description,
             "code": line.product_id.code,
             "qty": line.qty,
             "uom": line.uom_id.name,
             "unit_price": line.unit_price,
             "discount": line.discount,
             "tax_rate": line.tax_id.rate,
             "amount": line.amount,
         })
     is_cash = 'No'
     is_cheque = 'No'
     for obj in inv.payments:
         account_type = obj.payment_id.account_id.type
         if account_type in ("bank", "cash"):
             is_cash = 'Yes'
         if account_type in ("cheque"):
             is_cheque = 'Yes'
     data.update({
         "amount_subtotal": inv.amount_subtotal,
         "amount_discount": inv.amount_discount,
         "amount_tax": inv.amount_tax,
         "amount_total": inv.amount_total,
         "amount_paid": inv.amount_paid,
         "payment_terms": inv.related_id.payment_terms or "-",
         "is_cash": is_cash,
         "is_cheque": is_cheque,
         "currency_code": inv.currency_id.code,
         "tax_rate": round(inv.amount_tax * 100.0 / inv.amount_subtotal or 0, 2),
         "qty_total": inv.qty_total,
         "memo": inv.memo,
     })
     if inv.credit_alloc:
         data.update({
             "original_inv_subtotal": inv.credit_alloc[0].invoice_id.amount_subtotal,
         })
     return data
Beispiel #41
0
def report_render_odt(tmpl_name, data):
    print("REPORT_RENDER_ODT", tmpl_name, data)
    try:
        tmpl_data = get_report_template(tmpl_name, "odt")
    except:
        tmpl_data = get_report_template(tmpl_name, "odt2")  # XXX
    tmpl_f = BytesIO(tmpl_data)
    zf = zipfile.ZipFile(tmpl_f)

    f_out = BytesIO()
    zf_out = zipfile.ZipFile(f_out, "w")
    img_no = 1
    add_files = []
    for tmpl_fname in ("content.xml", "styles.xml"):
        getns = {
            "text": "urn:oasis:names:tc:opendocument:xmlns:text:1.0",
            "draw": "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0",
            "svg-com": "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0",
            "table": "urn:oasis:names:tc:opendocument:xmlns:table:1.0"
        }
        ns_manifest = "urn:oasis:names:tc:opendocument:xmlns:manifest:1.0"
        ns_svg = "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"
        f = zf.open(tmpl_fname)
        tree = etree.parse(f)
        open("/tmp/odt_template_orig.xml", "w").write(etree.tostring(tree, pretty_print=True).decode())

        chunks = get_text_chunks(tree)
        print("#" * 80)
        print("CHUNKS", [c[1] for c in chunks])
        found_expr = False
        expr = None
        expr_pos = []
        for i, (p, t) in enumerate(chunks):
            if i + 1 < len(chunks):
                next_t = chunks[i + 1][1]
            else:
                next_t = None
            if not found_expr:
                if t.find("{{") != -1 or next_t and t[-1] == "{" and next_t[0] == "{":
                    found_expr = True
                    expr = ""
                    expr_pos = []
            if found_expr:
                expr += t
                expr_pos.append(p)
                if expr.find("}}") != -1:
                    for p in expr_pos:
                        set_pos_text(p, "")
                    set_pos_text(expr_pos[0], expr)
                    print("EXPR", expr)
                    if not check_hbs_expression(expr):
                        raise Exception("Invalid expression: '%s'" % expr)
                    found_expr = False

        open("/tmp/odt_template_join.xml", "w").write(etree.tostring(tree, pretty_print=True).decode())

        chunks = get_text_chunks(tree)
        blocks = []
        level = 0
        for p, t in chunks:
            for expr in re.findall("{{[#/].*?}}", t):
                if expr[2] == "#":
                    blocks.append((p, expr, level))
                    level += 1
                elif expr[2] == "/":
                    level -= 1
                    blocks.append((p, expr, level))
        print("#" * 80)
        print("BLOCKS", [(b[1], b[2]) for b in blocks])
        pairs = []
        for i, (p, t, level) in enumerate(blocks):
            if t[2] == "#":
                found = False
                for p2, t2, level2 in blocks[i + 1:]:
                    if level2 == level:
                        pairs.append((p, t, p2, t2))
                        found = True
                        break
                if not found:
                    raise Exception("No closing expression found for %s" % t)
        print("PAIRS", [(t, t2) for p, t, p2, t2 in pairs])
        for p, t, p2, t2 in pairs:
            if p[0] == p2[0]:
                continue
            parent = get_common_parent(p[0], p2[0])
            start = stop = None
            for i, c in enumerate(parent):
                if check_el_contains(c, p[0]):
                    start = i
                if check_el_contains(c, p2[0]):
                    stop = i
            print("relocate pair: '%s' '%s'" % (t, t2))
            print("  parent=%s start=%s stop=%s" % (parent, start, stop))
            if stop > start + 1:
                remove_keep_tail(parent, start)
                remove_keep_tail(parent, stop - 1)
                if start > 0:
                    parent[start - 1].tail = (parent[start - 1].tail or "") + t
                else:
                    parent.text = (parent.text or "") + t
                parent[stop - 2].tail = t2 + (parent[stop - 2].tail or "")

        open("/tmp/odt_template_block.xml", "w").write(etree.tostring(tree, pretty_print=True).decode())

        def _repl(m):
            var = m.group(1)
            return "{{{odt_linebreak %s}}}" % var
        textp = tree.findall(".//*")
        for textel in textp:
            if not textel.text:
                continue
            if textel.text.find("{{") == -1:
                continue
            t = re.sub("{{\s*(\w+)\s*}}", _repl, textel.text)
            if t != textel.text:
                textel.text = t

        doc_tmpl = etree.tostring(tree, pretty_print=True, encoding="unicode")
        # XXX sometimes they're found as "”" instead of &#8221;
        doc_tmpl = doc_tmpl.replace("“", "\"")
        doc_tmpl = doc_tmpl.replace("”", "\"")
        doc_tmpl = doc_tmpl.replace("&#8220;", "\"")
        doc_tmpl = doc_tmpl.replace("&#8221;", "\"")

        open("/tmp/odt_template_use.xml", "w").write(doc_tmpl)
        odt_xml = template.render_template(doc_tmpl, data)  # XXX
        open("/tmp/odt_render_out.xml", "w").write(odt_xml)

        tree = etree.fromstring(odt_xml)
        for frame_el in tree.findall(".//draw:frame", namespaces={"draw": getns["draw"]}):
            title_el = frame_el.find("svg:title", namespaces={"svg": ns_svg})
            if title_el is not None:
                fname = title_el.text
            else:
                fname = None
            if not fname:
                continue
            img_path = utils.get_file_path(fname)
            if not os.path.exists(img_path):  # XXX
                continue
            new_zip_path = "Pictures/_img%d.png" % img_no
            img_no += 1
            image_el = frame_el[0]
            image_el.attrib['{http://www.w3.org/1999/xlink}href'] = new_zip_path
            add_files.append((new_zip_path, img_path, "image/png"))
            cx = frame_el.attrib["{%s}width" % getns["svg-com"]]
            cy = frame_el.attrib["{%s}height" % getns["svg-com"]]
            cx_unit = cx[-2] + cx[-1]
            cx = cx[:-2]
            cy_unit = cy[-2] + cy[-1]
            cy = cy[:-2]
            img = Image.open(img_path)
            w, h = img.size
            scale = min(float(cx) / w, float(cy) / h)
            cx2 = w * scale
            cy2 = h * scale
            frame_el.attrib["{%s}width" % getns["svg-com"]] = str(cx2) + cx_unit
            frame_el.attrib["{%s}height" % getns["svg-com"]] = str(cy2) + cy_unit

        odt_xml = etree.tostring(tree, pretty_print=True, encoding="unicode")
        zf_out.writestr(tmpl_fname, odt_xml)

    print("add_files", add_files)

    f = zf.open("META-INF/manifest.xml")
    tree = etree.parse(f)
    root = tree.getroot()
    for zip_path, img_path, media_type in add_files:
        el = etree.Element("{%s}file-entry" % ns_manifest)
        el.attrib["{%s}full-path" % ns_manifest] = zip_path
        el.attrib["{%s}media-type" % ns_manifest] = media_type
        root.append(el)
    manif_xml = etree.tostring(tree, pretty_print=True, encoding="unicode")
    zf_out.writestr("META-INF/manifest.xml", manif_xml)

    out_names = set(zf_out.namelist())
    for name in zf.namelist():
        if name in out_names:
            continue
        data = zf.read(name)
        zf_out.writestr(name, data)
    for zip_path, img_path, media_type in add_files:
        img_data = open(img_path, "rb").read()
        zf_out.writestr(zip_path, img_data)
    zf.close()
    zf_out.close()
    data = f_out.getvalue()
    f_out.close()
    return data
Beispiel #42
0
def report_render_odt(tmpl_name, data):
    print("REPORT_RENDER_ODT", tmpl_name, data)
    try:
        tmpl_data = get_report_template(tmpl_name, "odt")
    except:
        tmpl_data = get_report_template(tmpl_name, "odt2")  # XXX
    tmpl_f = BytesIO(tmpl_data)
    zf = zipfile.ZipFile(tmpl_f)

    f_out = BytesIO()
    zf_out = zipfile.ZipFile(f_out, "w")
    img_no = 1
    add_files = []
    for tmpl_fname in ("content.xml", "styles.xml"):
        getns = {
            "text": "urn:oasis:names:tc:opendocument:xmlns:text:1.0",
            "draw": "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0",
            "svg-com":
            "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0",
            "table": "urn:oasis:names:tc:opendocument:xmlns:table:1.0"
        }
        ns_manifest = "urn:oasis:names:tc:opendocument:xmlns:manifest:1.0"
        ns_svg = "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"
        f = zf.open(tmpl_fname)
        tree = etree.parse(f)
        open("/tmp/odt_template_orig.xml",
             "w").write(etree.tostring(tree, pretty_print=True).decode())

        chunks = get_text_chunks(tree)
        print("#" * 80)
        print("CHUNKS", [c[1] for c in chunks])
        found_expr = False
        expr = None
        expr_pos = []
        for i, (p, t) in enumerate(chunks):
            if i + 1 < len(chunks):
                next_t = chunks[i + 1][1]
            else:
                next_t = None
            if not found_expr:
                if t.find("{{") != -1 or next_t and t[-1] == "{" and next_t[
                        0] == "{":
                    found_expr = True
                    expr = ""
                    expr_pos = []
            if found_expr:
                expr += t
                expr_pos.append(p)
                if expr.find("}}") != -1:
                    for p in expr_pos:
                        set_pos_text(p, "")
                    set_pos_text(expr_pos[0], expr)
                    print("EXPR", expr)
                    if not check_hbs_expression(expr):
                        raise Exception("Invalid expression: '%s'" % expr)
                    found_expr = False

        open("/tmp/odt_template_join.xml",
             "w").write(etree.tostring(tree, pretty_print=True).decode())

        chunks = get_text_chunks(tree)
        blocks = []
        level = 0
        for p, t in chunks:
            for expr in re.findall("{{[#/].*?}}", t):
                if expr[2] == "#":
                    blocks.append((p, expr, level))
                    level += 1
                elif expr[2] == "/":
                    level -= 1
                    blocks.append((p, expr, level))
        print("#" * 80)
        print("BLOCKS", [(b[1], b[2]) for b in blocks])
        pairs = []
        for i, (p, t, level) in enumerate(blocks):
            if t[2] == "#":
                found = False
                for p2, t2, level2 in blocks[i + 1:]:
                    if level2 == level:
                        pairs.append((p, t, p2, t2))
                        found = True
                        break
                if not found:
                    raise Exception("No closing expression found for %s" % t)
        print("PAIRS", [(t, t2) for p, t, p2, t2 in pairs])
        for p, t, p2, t2 in pairs:
            if p[0] == p2[0]:
                continue
            parent = get_common_parent(p[0], p2[0])
            start = stop = None
            for i, c in enumerate(parent):
                if check_el_contains(c, p[0]):
                    start = i
                if check_el_contains(c, p2[0]):
                    stop = i
            print("relocate pair: '%s' '%s'" % (t, t2))
            print("  parent=%s start=%s stop=%s" % (parent, start, stop))
            if stop > start + 1:
                remove_keep_tail(parent, start)
                remove_keep_tail(parent, stop - 1)
                if start > 0:
                    parent[start - 1].tail = (parent[start - 1].tail or "") + t
                else:
                    parent.text = (parent.text or "") + t
                parent[stop - 2].tail = t2 + (parent[stop - 2].tail or "")

        open("/tmp/odt_template_block.xml",
             "w").write(etree.tostring(tree, pretty_print=True).decode())

        def _repl(m):
            var = m.group(1)
            return "{{{odt_linebreak %s}}}" % var

        textp = tree.findall(".//*")
        for textel in textp:
            if not textel.text:
                continue
            if textel.text.find("{{") == -1:
                continue
            t = re.sub("{{\s*(\w+)\s*}}", _repl, textel.text)
            if t != textel.text:
                textel.text = t

        doc_tmpl = etree.tostring(tree, pretty_print=True, encoding="unicode")
        # XXX sometimes they're found as "”" instead of &#8221;
        doc_tmpl = doc_tmpl.replace("“", "\"")
        doc_tmpl = doc_tmpl.replace("”", "\"")
        doc_tmpl = doc_tmpl.replace("&#8220;", "\"")
        doc_tmpl = doc_tmpl.replace("&#8221;", "\"")

        open("/tmp/odt_template_use.xml", "w").write(doc_tmpl)
        odt_xml = template.render_template(doc_tmpl, data)  # XXX
        open("/tmp/odt_render_out.xml", "w").write(odt_xml)

        tree = etree.fromstring(odt_xml)
        for frame_el in tree.findall(".//draw:frame",
                                     namespaces={"draw": getns["draw"]}):
            title_el = frame_el.find("svg:title", namespaces={"svg": ns_svg})
            if title_el is not None:
                fname = title_el.text
            else:
                fname = None
            if not fname:
                continue
            img_path = utils.get_file_path(fname)
            if not os.path.exists(img_path):  # XXX
                continue
            new_zip_path = "Pictures/_img%d.png" % img_no
            img_no += 1
            image_el = frame_el[0]
            image_el.attrib[
                '{http://www.w3.org/1999/xlink}href'] = new_zip_path
            add_files.append((new_zip_path, img_path, "image/png"))
            cx = frame_el.attrib["{%s}width" % getns["svg-com"]]
            cy = frame_el.attrib["{%s}height" % getns["svg-com"]]
            cx_unit = cx[-2] + cx[-1]
            cx = cx[:-2]
            cy_unit = cy[-2] + cy[-1]
            cy = cy[:-2]
            img = Image.open(img_path)
            w, h = img.size
            scale = min(float(cx) / w, float(cy) / h)
            cx2 = w * scale
            cy2 = h * scale
            frame_el.attrib["{%s}width" %
                            getns["svg-com"]] = str(cx2) + cx_unit
            frame_el.attrib["{%s}height" %
                            getns["svg-com"]] = str(cy2) + cy_unit

        odt_xml = etree.tostring(tree, pretty_print=True, encoding="unicode")
        zf_out.writestr(tmpl_fname, odt_xml)

    print("add_files", add_files)

    f = zf.open("META-INF/manifest.xml")
    tree = etree.parse(f)
    root = tree.getroot()
    for zip_path, img_path, media_type in add_files:
        el = etree.Element("{%s}file-entry" % ns_manifest)
        el.attrib["{%s}full-path" % ns_manifest] = zip_path
        el.attrib["{%s}media-type" % ns_manifest] = media_type
        root.append(el)
    manif_xml = etree.tostring(tree, pretty_print=True, encoding="unicode")
    zf_out.writestr("META-INF/manifest.xml", manif_xml)

    out_names = set(zf_out.namelist())
    for name in zf.namelist():
        if name in out_names:
            continue
        data = zf.read(name)
        zf_out.writestr(name, data)
    for zip_path, img_path, media_type in add_files:
        img_data = open(img_path, "rb").read()
        zf_out.writestr(zip_path, img_data)
    zf.close()
    zf_out.close()
    data = f_out.getvalue()
    f_out.close()
    return data
Beispiel #43
0
    def do_import(self, ids, context={}):
        print("import modules")
        obj = self.browse(ids)[0]
        path = utils.get_file_path(obj.file)
        zf = zipfile.ZipFile(path, "r")
        modules = {}
        for n in zf.namelist():
            if not n.endswith("/module.json"):
                continue
            path = n[:-len("/module.json")]
            data = zf.read(n).decode()
            vals = json.loads(data)
            name = vals["name"]
            module = {
                "name": name,
                "path": path,
                "info": vals,
                "model_files": [],
                "layout_files": [],
                "action_files": [],
                "template_files": [],
                "script_files": [],
            }
            modules[name] = module
        if not modules:
            raise Exception("No modules found")
        print("modules", modules.keys())

        ids = get_model("module").search([["name", "in", modules.keys()]])
        get_model("module").delete_modules(ids)

        for name, module in modules.items():
            info = module["info"]
            vals = {
                "name": name,
                "description": info.get("description"),
                "version": info.get("version"),
                "author": info.get("author"),
            }
            get_model("module").create(vals)

        for path in zf.namelist():
            found = False
            for name, module in modules.items():
                if path.startswith(module["path"] + "/"):
                    path2 = path[len(module["path"]) + 1:]
                    module = modules[name]
                    found = True
                    break
            if not found:
                continue
            if path2.startswith("models/") and path2.endswith(".xml"):
                module["model_files"].append(path)
            elif path2.startswith("layouts/") and path2.endswith(".xml"):
                module["layout_files"].append(path)
            elif path2.startswith("actions/") and path2.endswith(".json"):
                module["action_files"].append(path)
            elif path2.startswith("templates/") and path2.endswith(".hbs"):
                module["template_files"].append(path)
            elif path2.startswith("scripts/") and path2.endswith(".js"):
                module["script_files"].append(path)

        for mod_name, module in modules.items():
            for path in module["model_files"]:
                print("import model", path)
                n = os.path.splitext(os.path.basename(path))[0]
                data = zf.read(path).decode()
                root = etree.fromstring(data)
                vals = {
                    "name": root.attrib["name"],
                    "module_id": get_model("module").get(mod_name, require=True),
                }
                if root.attrib.get("string"):
                    vals["string"] = root.attrib["string"]
                if root.attrib.get("description"):  # XXX
                    vals["description"] = root.attrib["description"]
                res = get_model("model").search([["name", "=", vals["name"]]])
                if res:
                    model_id = res[0]
                    get_model("model").write([model_id], vals)
                else:
                    model_id = get_model("model").create(vals)

        def _import_field(el, model, mod_name):
            vals = {
                "model_id": get_model("model").get(model, require=True),
                "module_id": get_model("module").get(mod_name, require=True),
                "name": el.attrib["name"],
                "string": el.attrib["string"],
                "type": el.attrib["type"],
            }
            if el.attrib.get("relation"):
                vals["relation_id"] = get_model("model").get(el.attrib["relation"], require=True)
            if el.attrib.get("relfield"):
                vals["relfield_id"] = get_model("field").find_field(el.attrib["relation"], el.attrib["relfield"])
            if el.attrib.get("selection"):
                vals["selection"] = el.attrib["selection"]
            if el.attrib.get("required"):
                vals["required"] = True
            if el.attrib.get("readonly"):
                vals["readonly"] = True
            if el.attrib.get("function"):
                vals["function"] = el.attrib["function"]
            if el.attrib.get("default"):
                vals["default"] = el.attrib["default"]
            if el.attrib.get("search"):
                vals["search"] = True
            if el.attrib.get("condition"):
                vals["condition"] = el.attrib["condition"]
            if el.attrib.get("description"):
                vals["description"] = el.attrib["description"]
            get_model("field").create(vals)

        for mod_name, module in modules.items():
            for path in module["model_files"]:
                print("import fields #1", path)
                n = os.path.splitext(os.path.basename(path))[0]
                data = zf.read(path).decode()
                root = etree.fromstring(data)
                for el in root:
                    if el.tag != "field":
                        continue
                    if el.attrib.get("relfield"):
                        continue
                    _import_field(el, root.attrib["name"], mod_name)

        for mod_name, module in modules.items():
            for path in module["model_files"]:
                print("import fields #2", path)
                n = os.path.splitext(os.path.basename(path))[0]
                data = zf.read(path).decode()
                root = etree.fromstring(data)
                for el in root:
                    if el.tag != "field":
                        continue
                    if not el.attrib.get("relfield"):
                        continue
                    _import_field(el, root.attrib["name"], mod_name)

        for mod_name, module in modules.items():
            for path in module["layout_files"]:
                print("import layout", path)
                n = os.path.splitext(os.path.basename(path))[0]
                data = zf.read(path).decode()
                root = etree.fromstring(data)
                vals = {
                    "name": n,
                    "module_id": get_model("module").get(mod_name, require=True),
                    "type": root.tag.lower(),
                }
                if root.attrib.get("model"):
                    vals["model_id"] = get_model("model").get(root.attrib["model"], require=True)
                    del root.attrib["model"]
                if root.attrib.get("inherit"):
                    vals["inherit"] = root.attrib["inherit"]
                    del root.attrib["inherit"]
                vals["layout"] = etree.tostring(root, pretty_print=True).decode()
                get_model("view.layout").create(vals)

        for mod_name, module in modules.items():
            for path in module["action_files"]:
                print("import action", path)
                n = os.path.splitext(os.path.basename(path))[0]
                data = zf.read(path).decode()
                vals = json.loads(data)
                vals2 = {
                    "name": n,
                    "module_id": get_model("module").get(mod_name, require=True),
                }
                if vals.get("string"):
                    vals2["string"] = vals["string"]
                if vals.get("view"):
                    vals2["view"] = vals["view"]
                if vals.get("model"):
                    vals2["model_id"] = get_model("model").get(vals["model"], require=True)
                if vals.get("view_layout"):
                    vals2["view_layout_id"] = get_model("view.layout").get(vals["view_layout"], require=True)
                if vals.get("menu"):
                    vals2["menu_id"] = get_model("view.layout").get(vals["menu"], require=True)
                if vals.get("options"):
                    vals2["options"] = json.dumps(vals["options"])
                get_model("action").create(vals2)

        for mod_name, module in modules.items():
            for path in module["template_files"]:
                print("import template", path)
                n = os.path.splitext(os.path.basename(path))[0]
                data = zf.read(path).decode()
                vals = {
                    "name": n,
                    "module_id": get_model("module").get(mod_name, require=True),
                    "template": data,
                }
                get_model("template").create(vals)

        for mod_name, module in modules.items():
            for path in module["script_files"]:
                print("import script", path)
                n = os.path.splitext(os.path.basename(path))[0]
                data = zf.read(path).decode()
                vals = {
                    "name": n,
                    "module_id": get_model("module").get(mod_name, require=True),
                    "code": data,
                }
                get_model("script").create(vals)

        return {
            "next": {
                "name": "module",
            },
            "flash": "Modules imported successfully",
        }
Beispiel #44
0
def report_render_doc(tmpl_name, data):  # Do they delete the newline thing
    print("report_render_doc", tmpl_name, data)
    tmpl_data = get_report_template(tmpl_name, "docx")
    tmpl_f = BytesIO(tmpl_data)
    zf = zipfile.ZipFile(tmpl_f)

    ns = "http://schemas.openxmlformats.org/package/2006/relationships"
    f = zf.open("word/_rels/document.xml.rels")
    tree = etree.parse(f)
    rels = {}
    for el in tree.findall(".//ns:Relationship", namespaces={"ns": ns}):
        rels[el.attrib.get("Id")] = el.attrib.get("Target")
    print("rels", rels)

    ns = "http://schemas.openxmlformats.org/wordprocessingml/2006/main"
    f = zf.open("word/document.xml")
    tree = etree.parse(f)
    print("*** DOC_SRC *********************")
    print(etree.tostring(tree, pretty_print=True).decode())

    for el in tree.iterfind(".//w:p", namespaces={"w": ns}):
        vals = []
        start = False
        parent = el
        children = el.findall(".//w:r", namespaces={"w": ns})
        vals = []
        for child in children:
            grandchild = child.findall(".//w:t", namespaces={"w": ns})
            if grandchild and grandchild[0].text:
                text = grandchild[0].text
                if text and (text.find("{{") != -1 or text.find("}}") != -1
                             or start):
                    vals.append((text, child, grandchild[0]))
                    start = False if text.find("}}") != -1 and not (
                        text.find("{{") != -1) else True
        text = "".join([text for text, c, g in vals])
        for i, val in enumerate(vals):
            if i == 0:
                val[2].text = text
            else:
                parent.remove(val[1])

    images = {}
    change_list = []
    change_list.append("word/document.xml")
    for el in tree.iterfind(".//w:tc", namespaces={"w": ns}):
        expr = el.xpath("string()")
        if expr and expr.find("{{image") != -1:
            expr = expr.replace("\u201c", "\"")  # XXX
            expr = expr.replace("\u201d", "\"")
            m = re.search("{{image \"(.*?)\"", expr)
            if not m:
                raise Exception("Failed to parse image expression: %s" % expr)
            n = m.group(1)
            v = data.get(n)
            if v:
                res = el.findall(".//w:drawing", namespaces={"w": ns})
                if not res:
                    raise Exception("Failed to replace image")
                el_drawing = res[0]
                el_blip = el_drawing.find(
                    ".//a:blip",
                    namespaces={
                        "a":
                        "http://schemas.openxmlformats.org/drawingml/2006/main"
                    })
                embed = el_blip.attrib[
                    "{http://schemas.openxmlformats.org/officeDocument/2006/relationships}embed"]
                zip_path = rels[embed]
                change_list.append("word/" + zip_path)
                images[zip_path] = v
                el_extent = el_drawing.find(
                    ".//wp:extent",
                    namespaces={
                        "wp":
                        "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"
                    })
                cx = int(el_extent.attrib["cx"])
                cy = int(el_extent.attrib["cy"])
                img_path = utils.get_file_path(v)
                img = Image.open(img_path)
                w, h = img.size
                scale = min(float(cx) / w, float(cy) / h)
                cx2 = int(round(w * scale))
                cy2 = int(round(h * scale))
                el_extent.attrib["cx"] = str(cx2)
                el_extent.attrib["cy"] = str(cy2)
                el_ext = el_drawing.find(
                    ".//a:ext",
                    namespaces={
                        "a":
                        "http://schemas.openxmlformats.org/drawingml/2006/main"
                    })
                el_ext.attrib["cx"] = str(cx2)
                el_ext.attrib["cy"] = str(cy2)
            wts = el.findall(".//w:t", namespaces={"w": ns})
            for wt in wts:
                if wt.text and wt.text.find("{{image") != -1:
                    parent = wt.getparent()
                    grandparent = parent.getparent()
                    grandparent.remove(parent)

    for el in tree.iterfind(".//w:t", namespaces={"w": ns}):
        expr = el.text
        if expr.find("{{#") != -1 or expr.find("{{/") != -1:
            el_tr = el.getparent()
            while not el_tr.tag.endswith("}tr"):
                el_tr = el_tr.getparent()
            p = el_tr.getparent()
            # XXX
            if p:
                i = p.index(el_tr)
                p.remove(el_tr)
                p[i - 1].tail = expr

    doc_tmpl = etree.tostring(tree, pretty_print=True, encoding="unicode")
    doc_tmpl = doc_tmpl.replace("&#8220;", "\"")
    doc_tmpl = doc_tmpl.replace("&#8221;", "\"")
    doc_tmpl = doc_tmpl.replace("\u201c", "\"")
    doc_tmpl = doc_tmpl.replace("\u201d", "\"")
    print("*** DOC_TMPL *********************")
    for i, l in enumerate(doc_tmpl.split("\n")):
        print(i + 1, l)
    doc_xml = template.render_template(doc_tmpl, data)
    f_out = BytesIO()
    zf_out = zipfile.ZipFile(f_out, "w")
    for name in zf.namelist():
        print("XXX", name)
        if name in change_list:
            pass
        else:
            data = zf.read(name)
            zf_out.writestr(name, data)
    for zip_path, v in images.items():
        img_path = utils.get_file_path(v)
        img_data = open(img_path, "rb").read()
        zf_out.writestr("word/" + zip_path, img_data)
    zf_out.writestr("word/document.xml", doc_xml)
    zf.close()
    zf_out.close()
    data = f_out.getvalue()
    f_out.close()
    return data
Beispiel #45
0
    def get_data_sale_form(self, context={}):
        obj_id = int(context["refer_id"])
        obj = get_model("sale.order").browse(obj_id)
        dbname = database.get_active_db()
        settings = get_model("settings").browse(1)
        comp_name = settings.name
        comp_phone = settings.phone
        comp_fax = settings.fax
        comp_addr = settings.get_address_str()
        comp_tax_no = settings.tax_no
        contact = obj.contact_id
        cust_name = contact.name
        cust_fax = contact.fax
        cust_phone = contact.phone
        cust_tax_no = contact.tax_no
        cust_addr = contact.get_address_str()
        data = {
            "comp_name": comp_name,
            "comp_addr": comp_addr,
            "comp_phone": comp_phone or "-",
            "comp_fax": comp_fax or "-",
            "comp_tax_no": comp_tax_no or "-",
            "cust_name": cust_name,
            "cust_addr": cust_addr,
            "cust_phone": cust_phone or "-",
            "cust_fax": cust_fax or "-",
            "cust_tax_no": cust_tax_no or "-",
            "date": obj.date or "-",
            "number": obj.number or "-",
            "ref": obj.ref or "-",
            "delivery_date": obj.delivery_date or "-",
            "ship_method": obj.ship_method_id.name or "-",
            "payment_terms": obj.payment_terms or "-",
            "lines": [],
        }

        index = 0
        item = 0
        for line in obj.lines:
            if line.tax_id:
                break
            index += 1
        if not index:
            tax_rate = obj.lines[index].tax_id.rate
            tax_rate = tax_rate and tax_rate or "0"
        else:
            tax_rate = "0"

        if settings.logo:
            data["logo"] = get_file_path(settings.logo)
        for line in obj.lines:
            item += 1
            data["lines"].append({
                "item": item,
                "code": line.product_id.code,
                "name": line.product_id.name or "-",
                "description": line.description,
                "qty": line.qty,
                "uom": line.uom_id.name,
                "unit_price": line.unit_price,
                "tax_rate": line.tax_id.rate,
                "amount": line.amount,
            })
        data.update({
            "amount_subtotal": obj.amount_subtotal,
            "amount_tax": obj.amount_tax,
            "amount_total": obj.amount_total,
            "amount_total_words": utils.num2word(obj.amount_total),
            "other_info": obj.other_info or "-",
            "currency_code": obj.currency_id.code,
            "tax_rate": int(tax_rate),
            "qty_total": obj.qty_total
        })
        return data
Beispiel #46
0
    def do_import(self, ids, context={}):
        print("import modules")
        obj = self.browse(ids)[0]
        path = utils.get_file_path(obj.file)
        zf = zipfile.ZipFile(path, "r")
        modules = {}
        for n in zf.namelist():
            if not n.endswith("/module.json"):
                continue
            path = n[:-len("/module.json")]
            data = zf.read(n).decode()
            vals = json.loads(data)
            name = vals["name"]
            module = {
                "name": name,
                "path": path,
                "info": vals,
                "model_files": [],
                "layout_files": [],
                "action_files": [],
                "template_files": [],
                "script_files": [],
            }
            modules[name] = module
        if not modules:
            raise Exception("No modules found")
        print("modules", modules.keys())

        ids = get_model("module").search([["name", "in", modules.keys()]])
        get_model("module").delete_modules(ids)

        for name, module in modules.items():
            info = module["info"]
            vals = {
                "name": name,
                "description": info.get("description"),
                "version": info.get("version"),
                "author": info.get("author"),
            }
            get_model("module").create(vals)

        for path in zf.namelist():
            found = False
            for name, module in modules.items():
                if path.startswith(module["path"] + "/"):
                    path2 = path[len(module["path"]) + 1:]
                    module = modules[name]
                    found = True
                    break
            if not found:
                continue
            if path2.startswith("models/") and path2.endswith(".xml"):
                module["model_files"].append(path)
            elif path2.startswith("layouts/") and path2.endswith(".xml"):
                module["layout_files"].append(path)
            elif path2.startswith("actions/") and path2.endswith(".json"):
                module["action_files"].append(path)
            elif path2.startswith("templates/") and path2.endswith(".hbs"):
                module["template_files"].append(path)
            elif path2.startswith("scripts/") and path2.endswith(".js"):
                module["script_files"].append(path)

        for mod_name, module in modules.items():
            for path in module["model_files"]:
                print("import model", path)
                n = os.path.splitext(os.path.basename(path))[0]
                data = zf.read(path).decode()
                root = etree.fromstring(data)
                vals = {
                    "name": root.attrib["name"],
                    "module_id": get_model("module").get(mod_name,
                                                         require=True),
                }
                if root.attrib.get("string"):
                    vals["string"] = root.attrib["string"]
                if root.attrib.get("description"):  # XXX
                    vals["description"] = root.attrib["description"]
                res = get_model("model").search([["name", "=", vals["name"]]])
                if res:
                    model_id = res[0]
                    get_model("model").write([model_id], vals)
                else:
                    model_id = get_model("model").create(vals)

        def _import_field(el, model, mod_name):
            vals = {
                "model_id": get_model("model").get(model, require=True),
                "module_id": get_model("module").get(mod_name, require=True),
                "name": el.attrib["name"],
                "string": el.attrib["string"],
                "type": el.attrib["type"],
            }
            if el.attrib.get("relation"):
                vals["relation_id"] = get_model("model").get(
                    el.attrib["relation"], require=True)
            if el.attrib.get("relfield"):
                vals["relfield_id"] = get_model("field").find_field(
                    el.attrib["relation"], el.attrib["relfield"])
            if el.attrib.get("selection"):
                vals["selection"] = el.attrib["selection"]
            if el.attrib.get("required"):
                vals["required"] = True
            if el.attrib.get("readonly"):
                vals["readonly"] = True
            if el.attrib.get("function"):
                vals["function"] = el.attrib["function"]
            if el.attrib.get("default"):
                vals["default"] = el.attrib["default"]
            if el.attrib.get("search"):
                vals["search"] = True
            if el.attrib.get("condition"):
                vals["condition"] = el.attrib["condition"]
            if el.attrib.get("description"):
                vals["description"] = el.attrib["description"]
            get_model("field").create(vals)

        for mod_name, module in modules.items():
            for path in module["model_files"]:
                print("import fields #1", path)
                n = os.path.splitext(os.path.basename(path))[0]
                data = zf.read(path).decode()
                root = etree.fromstring(data)
                for el in root:
                    if el.tag != "field":
                        continue
                    if el.attrib.get("relfield"):
                        continue
                    _import_field(el, root.attrib["name"], mod_name)

        for mod_name, module in modules.items():
            for path in module["model_files"]:
                print("import fields #2", path)
                n = os.path.splitext(os.path.basename(path))[0]
                data = zf.read(path).decode()
                root = etree.fromstring(data)
                for el in root:
                    if el.tag != "field":
                        continue
                    if not el.attrib.get("relfield"):
                        continue
                    _import_field(el, root.attrib["name"], mod_name)

        for mod_name, module in modules.items():
            for path in module["layout_files"]:
                print("import layout", path)
                n = os.path.splitext(os.path.basename(path))[0]
                data = zf.read(path).decode()
                root = etree.fromstring(data)
                vals = {
                    "name": n,
                    "module_id": get_model("module").get(mod_name,
                                                         require=True),
                    "type": root.tag.lower(),
                }
                if root.attrib.get("model"):
                    vals["model_id"] = get_model("model").get(
                        root.attrib["model"], require=True)
                    del root.attrib["model"]
                if root.attrib.get("inherit"):
                    vals["inherit"] = root.attrib["inherit"]
                    del root.attrib["inherit"]
                vals["layout"] = etree.tostring(root,
                                                pretty_print=True).decode()
                get_model("view.layout").create(vals)

        for mod_name, module in modules.items():
            for path in module["action_files"]:
                print("import action", path)
                n = os.path.splitext(os.path.basename(path))[0]
                data = zf.read(path).decode()
                vals = json.loads(data)
                vals2 = {
                    "name": n,
                    "module_id": get_model("module").get(mod_name,
                                                         require=True),
                }
                if vals.get("string"):
                    vals2["string"] = vals["string"]
                if vals.get("view"):
                    vals2["view"] = vals["view"]
                if vals.get("model"):
                    vals2["model_id"] = get_model("model").get(vals["model"],
                                                               require=True)
                if vals.get("view_layout"):
                    vals2["view_layout_id"] = get_model("view.layout").get(
                        vals["view_layout"], require=True)
                if vals.get("menu"):
                    vals2["menu_id"] = get_model("view.layout").get(
                        vals["menu"], require=True)
                if vals.get("options"):
                    vals2["options"] = json.dumps(vals["options"])
                get_model("action").create(vals2)

        for mod_name, module in modules.items():
            for path in module["template_files"]:
                print("import template", path)
                n = os.path.splitext(os.path.basename(path))[0]
                data = zf.read(path).decode()
                vals = {
                    "name": n,
                    "module_id": get_model("module").get(mod_name,
                                                         require=True),
                    "template": data,
                }
                get_model("template").create(vals)

        for mod_name, module in modules.items():
            for path in module["script_files"]:
                print("import script", path)
                n = os.path.splitext(os.path.basename(path))[0]
                data = zf.read(path).decode()
                vals = {
                    "name": n,
                    "module_id": get_model("module").get(mod_name,
                                                         require=True),
                    "code": data,
                }
                get_model("script").create(vals)

        return {
            "next": {
                "name": "module",
            },
            "flash": "Modules imported successfully",
        }
Beispiel #47
0
def report_render_doc(tmpl_name, data):  # Do they delete the newline thing
    print("report_render_doc", tmpl_name, data)
    tmpl_data = get_report_template(tmpl_name, "docx")
    tmpl_f = BytesIO(tmpl_data)
    zf = zipfile.ZipFile(tmpl_f)

    ns = "http://schemas.openxmlformats.org/package/2006/relationships"
    f = zf.open("word/_rels/document.xml.rels")
    tree = etree.parse(f)
    rels = {}
    for el in tree.findall(".//ns:Relationship", namespaces={"ns": ns}):
        rels[el.attrib.get("Id")] = el.attrib.get("Target")
    print("rels", rels)

    ns = "http://schemas.openxmlformats.org/wordprocessingml/2006/main"
    f = zf.open("word/document.xml")
    tree = etree.parse(f)
    print("*** DOC_SRC *********************")
    print(etree.tostring(tree, pretty_print=True).decode())

    for el in tree.iterfind(".//w:p", namespaces={"w": ns}):
        vals = []
        start = False
        parent = el
        children = el.findall(".//w:r", namespaces={"w": ns})
        vals = []
        for child in children:
            grandchild = child.findall(".//w:t", namespaces={"w": ns})
            if grandchild and grandchild[0].text:
                text = grandchild[0].text
                if text and (text.find("{{") != -1 or text.find("}}") != -1 or start):
                    vals.append((text, child, grandchild[0]))
                    start = False if text.find("}}") != -1 and not (text.find("{{") != -1) else True
        text = "".join([text for text, c, g in vals])
        for i, val in enumerate(vals):
            if i == 0:
                val[2].text = text
            else:
                parent.remove(val[1])

    images = {}
    change_list = []
    change_list.append("word/document.xml")
    for el in tree.iterfind(".//w:tc", namespaces={"w": ns}):
        expr = el.xpath("string()")
        if expr and expr.find("{{image") != -1:
            expr = expr.replace("\u201c", "\"")  # XXX
            expr = expr.replace("\u201d", "\"")
            m = re.search("{{image \"(.*?)\"", expr)
            if not m:
                raise Exception("Failed to parse image expression: %s" % expr)
            n = m.group(1)
            v = data.get(n)
            if v:
                res = el.findall(".//w:drawing", namespaces={"w": ns})
                if not res:
                    raise Exception("Failed to replace image")
                el_drawing = res[0]
                el_blip = el_drawing.find(
                    ".//a:blip", namespaces={"a": "http://schemas.openxmlformats.org/drawingml/2006/main"})
                embed = el_blip.attrib["{http://schemas.openxmlformats.org/officeDocument/2006/relationships}embed"]
                zip_path = rels[embed]
                change_list.append("word/" + zip_path)
                images[zip_path] = v
                el_extent = el_drawing.find(
                    ".//wp:extent", namespaces={"wp": "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"})
                cx = int(el_extent.attrib["cx"])
                cy = int(el_extent.attrib["cy"])
                img_path = utils.get_file_path(v)
                img = Image.open(img_path)
                w, h = img.size
                scale = min(float(cx) / w, float(cy) / h)
                cx2 = int(round(w * scale))
                cy2 = int(round(h * scale))
                el_extent.attrib["cx"] = str(cx2)
                el_extent.attrib["cy"] = str(cy2)
                el_ext = el_drawing.find(
                    ".//a:ext", namespaces={"a": "http://schemas.openxmlformats.org/drawingml/2006/main"})
                el_ext.attrib["cx"] = str(cx2)
                el_ext.attrib["cy"] = str(cy2)
            wts = el.findall(".//w:t", namespaces={"w": ns})
            for wt in wts:
                if wt.text and wt.text.find("{{image") != -1:
                    parent = wt.getparent()
                    grandparent = parent.getparent()
                    grandparent.remove(parent)

    for el in tree.iterfind(".//w:t", namespaces={"w": ns}):
        expr = el.text
        if expr.find("{{#") != -1 or expr.find("{{/") != -1:
            el_tr = el.getparent()
            while not el_tr.tag.endswith("}tr"):
                el_tr = el_tr.getparent()
            p = el_tr.getparent()
            # XXX
            if p:
                i = p.index(el_tr)
                p.remove(el_tr)
                p[i - 1].tail = expr

    doc_tmpl = etree.tostring(tree, pretty_print=True, encoding="unicode")
    doc_tmpl = doc_tmpl.replace("&#8220;", "\"")
    doc_tmpl = doc_tmpl.replace("&#8221;", "\"")
    doc_tmpl = doc_tmpl.replace("\u201c", "\"")
    doc_tmpl = doc_tmpl.replace("\u201d", "\"")
    print("*** DOC_TMPL *********************")
    for i, l in enumerate(doc_tmpl.split("\n")):
        print(i + 1, l)
    doc_xml = template.render_template(doc_tmpl, data)
    f_out = BytesIO()
    zf_out = zipfile.ZipFile(f_out, "w")
    for name in zf.namelist():
        print("XXX", name)
        if name in change_list:
            pass
        else:
            data = zf.read(name)
            zf_out.writestr(name, data)
    for zip_path, v in images.items():
        img_path = utils.get_file_path(v)
        img_data = open(img_path, "rb").read()
        zf_out.writestr("word/" + zip_path, img_data)
    zf_out.writestr("word/document.xml", doc_xml)
    zf.close()
    zf_out.close()
    data = f_out.getvalue()
    f_out.close()
    return data