这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 1.0.1

- UI friendly changes and fixes.
- Add Angular2 usage sample.

## 1.0.0

- Fix UMD lib. Add browser usage sample (breaking changes will go to 2.x)
Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ Billing Module JS

npm install billing

* Implements base billing standart.
* Data binding frameworks friendly.
* Example: [BillingJs Demo (Angular2)](https://plnkr.co/n0srTG)

## Usage

### Right constructor ([samples/node/rightConstructor.js](samples/node/rightConstructor.js))
Expand Down Expand Up @@ -75,6 +79,10 @@ bill.toJson() //A JSON object (without circular references)
boolean <item>.isValid // check validity
<item>.errors // errors format [{ propertyName: { validationName: 'Human readable error' }}]

### Other

<item>.state // Unused instance variable available for UI purposes

## Using the nomenclature ([samples/node/usingNomenclature.js](samples/node/usingNomenclature.js))
```javascript
var billing = require('../../').Billing;
Expand Down
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "billing",
"version": "1.0.0",
"version": "1.0.1",
"description": "Billing Module Js",
"author": "AlexV",
"repository": {
Expand All @@ -20,7 +20,8 @@
"typings": "typings install",
"test": "karma start karma.conf.js",
"build": "tsc -d",
"dist": "webpack --progress --profile --bail"
"dist": "webpack --progress --profile --bail",
"sample-angular": "webpack-dev-server --content-base samples/browser/angular2/"
},
"devDependencies": {
"awesome-typescript-loader": "^2.2.4",
Expand All @@ -35,7 +36,8 @@
"source-map": "^0.5.6",
"typescript": "^2.0.0",
"typings": "^1.3.3",
"webpack": "^1.13.2"
"webpack": "^1.13.2",
"webpack-dev-server": "^1.16.2"
},
"typings": "./lib/index.d.ts",
"files": [
Expand Down
9 changes: 9 additions & 0 deletions samples/browser/angular2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
### BillingJs Demo (Angular2)

Demonstrating BillingJs

GitHub: [https://github.com/AlexVangelov/billing-js](https://github.com/AlexVangelov/billing-js)

[![npm version](https://badge.fury.io/js/billing.svg)](https://badge.fury.io/js/billing)
[![Build status](https://travis-ci.org/AlexVangelov/billing-js.svg)](https://travis-ci.org/AlexVangelov/billing-js)

46 changes: 46 additions & 0 deletions samples/browser/angular2/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
System.config({
//use typescript for compilation
transpiler: 'typescript',
//typescript compiler options
typescriptOptions: {
emitDecoratorMetadata: true
},
paths: {
'npm:': 'https://unpkg.com/'
},
//map tells the System loader where to look for things
map: {

'app': './src',

'@angular/core': 'npm:@angular/core@2.0.2/bundles/core.umd.js',
'@angular/common': 'npm:@angular/common@2.0.2/bundles/common.umd.js',
'@angular/compiler': 'npm:@angular/compiler@2.0.2/bundles/compiler.umd.js',
'@angular/platform-browser': 'npm:@angular/platform-browser@2.0.2/bundles/platform-browser.umd.js',
'@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic@2.0.2/bundles/platform-browser-dynamic.umd.js',
'@angular/http': 'npm:@angular/http@2.0.2/bundles/http.umd.js',
'@angular/router': 'npm:@angular/router@2.0.2/bundles/router.umd.js',
'@angular/forms': 'npm:@angular/forms@2.0.2/bundles/forms.umd.js',

'@angular/core/testing': 'npm:@angular/core@2.0.2/bundles/core-testing.umd.js',
'@angular/common/testing': 'npm:@angular/common@2.0.2/bundles/common-testing.umd.js',
'@angular/compiler/testing': 'npm:@angular/compiler@2.0.2/bundles/compiler-testing.umd.js',
'@angular/platform-browser/testing': 'npm:@angular/platform-browser@2.0.2/bundles/platform-browser-testing.umd.js',
'@angular/platform-browser-dynamic/testing': 'npm:@angular/platform-browser-dynamic@2.0.2/bundles/platform-browser-dynamic-testing.umd.js',
'@angular/http/testing': 'npm:@angular/http@2.0.2/bundles/http-testing.umd.js',
'@angular/router/testing': 'npm:@angular/router@2.0.2/bundles/router-testing.umd.js',

'rxjs': 'npm:rxjs',
'typescript': 'npm:typescript@2.0.2/lib/typescript.js'
},
//packages defines our app package
packages: {
app: {
main: './main.ts',
defaultExtension: 'ts'
},
rxjs: {
defaultExtension: 'js'
}
}
});
29 changes: 29 additions & 0 deletions samples/browser/angular2/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<!DOCTYPE html>
<html>

<head>
<base href="." />
<title>BillingJs Playground</title>
<link rel="stylesheet" href="style.css" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<script src="https://unpkg.com/zone.js/dist/zone.js"></script>
<script src="https://unpkg.com/zone.js/dist/long-stack-trace-zone.js"></script>
<script src="https://unpkg.com/reflect-metadata@0.1.3/Reflect.js"></script>
<script src="https://unpkg.com/systemjs@0.19.31/dist/system.js"></script>
<!-- loading BillingJs outside System.js as demo for other frameworks -->
<!--<script src='https://unpkg.com/billing@1.0.0/dist/billing.js'></script>-->
<script src='/billing.js'></script>
<script src="config.js"></script>
<script>
System.import('app')
.catch(console.error.bind(console));
</script>
</head>

<body>
<div class='container' style='margin-bottom: 100px;'>
<widget-billing>Loading... </widget-billing>
</div>
</body>
</html>
5 changes: 5 additions & 0 deletions samples/browser/angular2/src/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
//main entry point
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { WidgetBillingModule } from './widget/billing';

platformBrowserDynamic().bootstrapModule(WidgetBillingModule)
95 changes: 95 additions & 0 deletions samples/browser/angular2/src/widget/billing.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<h4>
<button class='btn btn-default pull-right' (click)='editModifier()'>- Discount / + Surcharge</button>
BillingJs Sample (Angular2)
<p><small>npm: <a href='https://www.npmjs.com/package/billing' target='_blank'>https://www.npmjs.com/package/billing</a></small></p>
</h4>
<div *ngIf='bill.errors' class='text-danger'>{{ bill.errors.messages.join(', ') }}</div>
<div class="panel panel-default">
<div class="panel-heading">
<button class='btn btn-default pull-right' (click)='editCharge()'>+ Add</button>
<h4>Charges</h4>
</div>
<!-- charges -->
<div class="list-group">
<div *ngFor='let charge of bill.charges'>
<button *ngIf='!charge.state' (click)='editCharge(charge)' class="list-group-item" [ngClass]="{ 'active': isSelected(charge), 'list-group-item-danger': !charge.isValid }">
<h4 class="list-group-item-heading">
<div class='pull-right'>{{ charge.finalValue | currency:'USD':true:'1.2-2' }}</div>
{{ charge.qty }} * {{ charge.price | currency:'USD':true:'1.2-2' }}
<small>{{ charge.name }}</small>
</h4>
<p class="list-group-item-text">{{ charge.description }}</p>
</button>
<button style='padding-left: 40px; border-top-style: dashed;' *ngIf='charge.modifier && !charge.modifier.state' (click)='editModifier(charge.modifier)' class="list-group-item" [ngClass]="{ 'active': isSelected(charge.modifier), 'list-group-item-danger': !charge.modifier.isValid }">
<h4 class="list-group-item-heading">
<div class='pull-right'>{{ charge.modifier.value | currency:'USD':true:'1.2-2' }}</div>
{{ labelForModifier(charge.modifier) }}
</h4>
</button>
</div>
</div>
<div class="list-group">
<div *ngFor='let modifier of globalModifiers'>
<button *ngIf='!modifier.state' (click)='editModifier(modifier)' class="list-group-item global-modifier" [ngClass]="{ 'active': isSelected(modifier), 'list-group-item-danger': !modifier.isValid }">
<h4 class="list-group-item-heading">
<div class='pull-right'>{{ modifier.value | currency:'USD':true:'1.2-2' }}</div>
{{ labelForModifier(modifier) }}
</h4>
</button>
</div>
</div>
<div class='panel-footer'>
<h4 class="list-group-item-heading">
<strong class='pull-right'>{{ bill.total | currency:'USD':true:'1.2-2' }}</strong>
Total
</h4>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<button (click)='editPayment()' class='btn btn-default pull-right'>+ Add</button>
<h4>Payments</h4>
</div>
<div class="list-group">
<div *ngFor='let payment of bill.payments'>
<button *ngIf='!payment.state' (click)='editPayment(payment)' class="list-group-item" [ngClass]="{ 'active': isSelected(payment), 'list-group-item-danger': !payment.isValid }">
<h4 class="list-group-item-heading">
<div class='pull-right'>{{ payment.value | currency:'USD':true:'1.2-2' }}</div>
{{ payment.name }}
</h4>
</button>
</div>
</div>
<div class='panel-footer'>
<h4 class="list-group-item-heading">
<strong class='pull-right' [ngClass]="{ 'text-danger': bill.balance > 0 }">{{ bill.balance | currency:'USD':true:'1.2-2' }}</strong>
Balance
</h4>
</div>
</div>
<div>
<button class='btn btn-default btn-sm' (click)='showJson()'>toJson()</button>
<button class='btn btn-default btn-sm' (click)='reset()'>Reset</button>
<a class='btn btn-link btn-sm pull-right' href='https://github.com/AlexVangelov/billing-js' target='_blank'>
<img width=24 src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIGlkPSJMYXllcl8xIiB4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjQwcHgiIGhlaWdodD0iNDBweCIgdmlld0JveD0iMTIgMTIgNDAgNDAiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMTIgMTIgNDAgNDAiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxwYXRoIGZpbGw9IiMzMzMzMzMiIGQ9Ik0zMiAxMy40Yy0xMC41IDAtMTkgOC41LTE5IDE5YzAgOC40IDUuNSAxNS41IDEzIDE4YzEgMC4yIDEuMy0wLjQgMS4zLTAuOWMwLTAuNSAwLTEuNyAwLTMuMiBjLTUuMyAxLjEtNi40LTIuNi02LjQtMi42QzIwIDQxLjYgMTguOCA0MSAxOC44IDQxYy0xLjctMS4yIDAuMS0xLjEgMC4xLTEuMWMxLjkgMC4xIDIuOSAyIDIuOSAyYzEuNyAyLjkgNC41IDIuMSA1LjUgMS42IGMwLjItMS4yIDAuNy0yLjEgMS4yLTIuNmMtNC4yLTAuNS04LjctMi4xLTguNy05LjRjMC0yLjEgMC43LTMuNyAyLTUuMWMtMC4yLTAuNS0wLjgtMi40IDAuMi01YzAgMCAxLjYtMC41IDUuMiAyIGMxLjUtMC40IDMuMS0wLjcgNC44LTAuN2MxLjYgMCAzLjMgMC4yIDQuNyAwLjdjMy42LTIuNCA1LjItMiA1LjItMmMxIDIuNiAwLjQgNC42IDAuMiA1YzEuMiAxLjMgMiAzIDIgNS4xYzAgNy4zLTQuNSA4LjktOC43IDkuNCBjMC43IDAuNiAxLjMgMS43IDEuMyAzLjVjMCAyLjYgMCA0LjYgMCA1LjJjMCAwLjUgMC40IDEuMSAxLjMgMC45YzcuNS0yLjYgMTMtOS43IDEzLTE4LjFDNTEgMjEuOSA0Mi41IDEzLjQgMzIgMTMuNHoiLz48L3N2Zz4=">
View on GitHub
</a>
</div>

<div class="modal show" *ngIf='selectedItem' id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document" [ngSwitch]="dialogType">
<widget-charge *ngSwitchCase="'charge'" [charge]='selectedItem' (done)='done($event)'></widget-charge>
<widget-modifier *ngSwitchCase="'modifier'" [modifier]='selectedItem' [charges]='bill.charges' (done)='done($event)'></widget-modifier>
<widget-payment *ngSwitchCase="'payment'" [payment]='selectedItem' (done)='done($event)'></widget-payment>
<div *ngSwitchCase="'json'" class="modal-content">
<div class="panel-heading">
<button type="button" class="close" (click)='done(true)' aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="myModalLabel">toJson()</h4>
</div>
<div class="modal-body">
<div *ngIf='!bill.isValid' class="alert alert-danger" role="alert">{{ bill.errors.messages.join(', ') }}</div>
<pre style='max-height: 400px; overflow: auto;'>{{ bill.toJson() | json }}</pre>
</div>
</div>
</div>
</div>
100 changes: 100 additions & 0 deletions samples/browser/angular2/src/widget/billing.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import { Component, NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { ReactiveFormsModule } from '@angular/forms';

import { WidgetCharge } from './charge';
import { WidgetModifier } from './modifier';
import { WidgetPayment } from './payment';

declare var billingJs: any;

@Component({
selector: 'widget-billing',
templateUrl: 'src/widget/billing.html'
})
export class WidgetBilling {
selectedItem :any;
selectedCollection :any;
bill :any;
dialogType :any;

constructor() {
this.bill = billingJs.Billing.bills.new();

this.bill = billingJs.Billing.bills.new();
this.bill.charges.new({ price: 8.3, name: 'Umbrella', description: 'Unmatched quality and classic design' });
this.bill.charges.new({ price: 135, name: 'Briefcase', description: 'High-quality ballistic nylon fabric',
modifier: { percentRatio: -0.1 } });
this.bill.charges.new({ qty: 3, price: .65, description: 'Accessories' });
this.bill.payments.new({ name: 'Cash' });
}

private buildCollectionItem() :any {
let item = this.selectedCollection.new();
item.state = true; //state is for UI purposes (not used in billing)
return item;
}

editCharge(charge ?:any) {
this.selectedCollection = this.bill.charges;
this.selectedItem = charge || this.buildCollectionItem();
this.dialogType = 'charge';
}
editModifier(modifier ?:any) {
this.selectedCollection = this.bill.modifiers;
this.selectedItem = modifier || this.buildCollectionItem();
this.dialogType = 'modifier';
}
editPayment(payment ?:any) {
this.selectedCollection = this.bill.payments;
this.selectedItem = payment || this.buildCollectionItem();
this.dialogType = 'payment';
}

done(modified :boolean) {
if (!modified && this.selectedItem.state) this.selectedItem.delete();
delete this.selectedItem.state;
delete this.selectedItem;
delete this.dialogType;
if (modified) this.bill.isValid;
}

isSelected(item) {
return item === this.selectedItem;
}

labelForModifier(modifier :any) {
let r = modifier.percentRatio;
let s = r > 0 ? '+' : '';
let label = r ? s + (r * 100) + '%' : '';
return `${label} ${modifier.value > 0 ? 'Surcharge' : 'Discount'}`;
}

showJson() {
this.selectedItem = this.bill;
this.dialogType = 'json';
}

reset() {
this.bill = billingJs.Billing.bills.new();
}

get globalModifiers() {
return this.bill.modifiers.filter( mod => {
return !mod.charge;
});
}
}

@NgModule({
imports: [ BrowserModule, ReactiveFormsModule ],
declarations: [
WidgetBilling,
WidgetCharge,
WidgetModifier,
WidgetPayment
],
bootstrap: [ WidgetBilling ],
schemas: [ CUSTOM_ELEMENTS_SCHEMA ]
})
export class WidgetBillingModule {}
Loading